React源码 Suspense 和 ReactLazy
import React, { Suspense, lazy } from 'react' const LazyComp = lazy(() => import('./lazy.js')) let data = ''
let promise = ''
function requestData() {
if (data) return data
if (promise) throw promise
promise = new Promise(resolve => {
setTimeout(() => {
data = 'Data resolved'
resolve()
}, 2000)
})
throw promise
} function SuspenseComp() {
const data = requestData() return <p>{data}</p>
} export default () => (
<Suspense fallback="loading data">
<SuspenseComp />
<LazyComp />
</Suspense>
)
首先我们看到 export 出去的这个组件,他是一个 function component。然后他使用了 Suspense 。然后给他一个 props ,fallback,fallback 里面就是我们一开始看到的 loading data 。然后里面是两个组件
import React from 'react' export default () => <p>Lazy Comp</p>
有了这个组件之后,在 index.js 里面实现异步加载就变得非常的简单
const LazyComp = lazy(() => import('./lazy.js'))
调用 lazy , 传入一个方法,里面 import lazy.js。 Lazy Comp 跟 Data resolved 是一起显示出来的,那么这就是 Suspense 的一个特点,在 Suspense 内部有多个组件,他要等所有组件都 resolve 之后,他才会把 fallback 去掉,然后显示出这里面的内容,有任何一个还处于 pending 状态的,那么他还是会显示 fallback .
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/ import type {LazyComponent, Thenable} from 'shared/ReactLazyComponent'; import {REACT_LAZY_TYPE} from 'shared/ReactSymbols'; export function lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T> {
return {
$$typeof: REACT_LAZY_TYPE,
_ctor: ctor,
// React uses these fields to store the result.
_status: -1,
_result: null,
};
}
发现 ReactLazy.js 里面的源码也非常简单,lazy 是一个方法,然后他接收一个方法,并且返回一个 Thenable ,Thenable 什么意思呢?就是 promise 这样的一个对象。具有 .then , 而且这个 .then 是个 function 。他接收这个参数,他返回的是一个 LazyComponent 。返回的一个对象,里面有 $$typeof, 是 REACT_LAZY_TYPE。第一个返回的是 _ctor,这个 _ctor 就等于传进来的参数,这个方法,第三个 _status,这个是用来记录 Thenable 的一个状态的,因为在 react 渲染当中,在渲染到 LazyComponent 的时候,他会去调用这个 ctor 。然后返回一个 Thenable 的对象,一般来说我们认为他是一个 Promise , 这个时候 Promise 是属于 pending 状态的,对应的是 -1 。后面到 resolve 或者 reject 的时候,这个 _status 会变化,_result 是用来记录这个对象 resolve 之后返回的那个属性,lazy 里面最终返回出来的组件会放到
最新文章
- 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
- Linux - 变量
- 一个PHP混淆后门的分析
- Android系统用于Activity的标准Intent
- noip赛前小结2
- 4-3 yum命令
- E8.ITSM IT运维服务管理系统
- centos 给鼠标右击添加 “打开终端” 菜单项
- 克隆虚拟机后修改MAC地址
- XSL相关
- java transient修饰符
- MyBatis的类型自定义映射
- Python爬虫基本原理
- 一文了解Python的线程
- 基于stm32的水质监测系统项目基础部分详细记录
- cp备份操作时如何忽略指定的目录
- scrapy 简单爬虫实验
- 2016年3月10日Android实习日记
- c++ vector常见用法
- 前端开发VScode常用插件
热门文章
- failed to execute /bin/bash: Resource temporarily unavailable的问题处理
- wkhtmltopdf cpdf HTML转pdf 及pdf合并
- 终于有人把elasticsearch原理讲通了
- SCIE和SCI
- 第十二节:Asp.Net Core 之分布式缓存(SQLServer和Redis)
- 模拟 + 暴搜 --- Help Me with the Game
- VueTreeselect出现unknown解决方法
- CLH lock 原理及JAVA实现
- STM32Cube基础工程配置
- springMVC 任意文件读取相关路径