React 源码(一)

76 阅读2分钟

这周,我将开始对React的源码深入的学习,并在这里做一个简单的记录📝与分享。

本地调试源码

1、从facebook/react 项目拉取最新的源码 2、基于最新的源码构建react、react-dom 3、创建独立的HTML文件,通过script标签加载本地的UMD文件。

# 克隆 
git clone https://github.com/facebook/react.git

# 安装依赖 
cd react & yarn 

# 构建
yarn build react/index,react-dom/index --type=UMD

⚠️:

当我们尝试以UMD的格式构建react和react-dom的时候,发现在build文件里并没有出现我们想要的UMD格式的文件, 查看打包文件:发现并没有UMD的打包类型,原来构建umd产物的代码已经被删掉啦:

image.png

为了快速调试,我直接将代码回退到删除umd的版本:

git checkout -b debug-react 0c245df

尝试构建,正常输出

image.png

宏观结构

  • react

基础包,只提供定义React 组件(ReactElement)的必要函数,可以理解为一个api的库

  • react-dom

react的渲染器,将react-reconciler中的运行结果输出到web界面,大多数场景下,能用到此包的就是一个入口函数,ReactDOM.render(<App/>,ducument.getElementById('root')),其他的都是react中的api

  • react-reconciler

枢纽,综合协调react、react-dom、scheduler各包之间的调用和配合,管理react应用状态的输入和结果的输出,将结果传递给渲染器

  • scheduler

调度机制的核心实现,控制由react-reconciler提供的回调函数的执行时机。

两大工作循环

image.png

1、任务调度循环

位于scheduler,需要循环调用,控制所有task的调用

2、fiber构造循环

位于react-reconciler,控制fiber树的构成,整个过程是一个深度优先遍历

主干逻辑:

大循环(任务调度循环)负责调度task,小循环(fiber构造循环)负责实现task

  • 输入:每一次的更新(新增、删除、修改节点)视为一次更新需求(目的是更新DOM节点)

  • 注册调度任务:react-reconciler收到更新需求的时候,并不会立即构造fiber树,而是去调度中心scheduler中注册一个新任务task,即把更新续期转换为一个task

  • 执行调度任务(输出):scheduler通过任务调度循环来执行task,task的执行过程又回到啦react-reconciler包中

    • fiber循环结构是task实现的第一步,循环完成之后会构造出新的fiber树
    • commitRoot是task实现的第二步,把最新的fiber树最终渲染到页面上,task完成