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 里面最终返回出来的组件会放到
React源码 Suspense 和 ReactLazy的更多相关文章
- React躬行记(16)——React源码分析
React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...
- React源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...
- React源码解析:ReactElement
ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ...
- react 源码之setState
今天看了react源码,仅以记录. 1:monorepo (react 的代码管理方式) 与multirepo 相对. monorepo是单代码仓库, 是把所有相关项目都集中在一个代码仓库中,每个mo ...
- React 源码剖析系列 - 不可思议的 react diff
简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
- React 源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...
- 读react源码准备
git源码地址:https://github.com/facebook/react react 里面就是 react源码 react里面的react文件夹就是react源码,react源码非常的少,总 ...
- react源码之render
1.最近学习react源码,刚刚入门,看了render的原理,到了fiberRoot的创建 如图:
- React源码之组件的实现与首次渲染
react: v15.0.0 本文讲 组件如何编译 以及 ReactDOM.render 的渲染过程. babel 的编译 babel 将 React JSX 编译成 JavaScript. 在 ba ...
随机推荐
- [算法模版]AC自动机
[算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义 ...
- 每日一问:你了解 Java 虚拟机结构么?
对于从事 C/C++ 程序员开发的小伙伴来说,在内存管理领域非常头疼,因为他们总是需要对每一个 new 操作去写配对的 delete/free 代码.而对于我们 Android 乃至 Java 程序员 ...
- concurrent (二)AQS
参考文档: https://www.cnblogs.com/waterystone/p/4920797.html
- IDEA-Maven的Dependencies中出现红色波浪线
解决方法:移除相关依赖,再重新添加即可 情况及具体解决方法如下:1.在Maven Project中 Dependencies 出现红色波浪线 2.查询本地仓库:jar包已存在 3.解决方法:3.1.从 ...
- [Gamma]Scrum Meeting#9
github 本次会议项目由PM召开,时间为6月4日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译坐 ...
- 【2019年05月13日】A股ROE最高排名
个股滚动ROE = 最近4个季度的归母净利润 / ((期初归母净资产 + 期末归母净资产) / 2). 查看更多个股ROE最高排名. 兰州民百(SH600738) - 滚动ROE:86.45% - 滚 ...
- Python 3.X 练习集100题 01
有以下几个数字:1.2.3.4.5,能组成多少个互不相同且无重复数字的三位数?都是多少? 方法1: import itertools from functools import reduce lyst ...
- spring boot 从开发到部署(二)—重启服务
上篇中,我们开发并部署上线了一个 spring boot 项目.现在需要编写服务重启脚本,保证服务器重启后能够自动的运行我们的项目. /home/web/sprint-web/restart-happ ...
- Oracle账号,用于下载jdk
账号:liwei@xiaostudy.com 密码:OracleTest1234
- Windows和Linux简单命令的总结
MS-DOS 命令提示符(cmd) 启动: Win+R,输入cmd回车 切换盘符 盘符名称: 进入文件夹 cd ...