本篇文章学习React源码,根据每个阶段进行源码debugger学习。
这里提供如何在本地打debugger:github.com/sunkuangdon…
如有不明白的,请留言(映射我已经做好了,大家可以在 react/build/node_modules/react-dom/cjs/react-dom.development.js 文件中最上面log一下试试,看控制台是否能打印出来)。
这个也是本人自学的项目,之后可能会有备注,觉得不对的大家可以评论给我,或者在备注中说明,我会看到。
希望你的备注格式是:/* name: 指出错误 */
,谢谢大家
源码目录结构
我们先来了解如下:
- 源码的目录结构是如何划分的
- 调度器、渲染器、协调器所在目录在哪儿
顶层目录
React源码的顶层目录分为三个文件夹:
根目录
├── fixtures # 包含给贡献者准备的小型React测试项目
├── packages # 包含元数据(比如 package.json)和React项目中pack
age的源码
├── scripts # 各种工具链的脚本,比如git、jest、eslint等
复制代码
首先我们关注packages文件夹内部:
- react文件:里面有许多和平台无关的代码。
- 比如 react.Children、react.Component、react.useState等等。(index.js中能看到)
- scheduler文件:调度器相关的代码
- react-reconciler文件:协调器相关代码
- react-dom文件:渲染器相关代码
- 根DOM操作相关的API都在这里
- shared文件夹:公共方法的代码
- react-reconclier文件夹:实验性的包
- 虽然是实验性的,内部很多功能还未开放。但是他一边对接Scheduler,一边对接不同平台的Renender。
首屏渲染流程
我们先来看看浏览器调用栈中显示出的React架构样子:
- 运行我们的a-react-demo项目,浏览器中打开调试工具进入Performance面板
- 刚开始是一片空白,点击下面这个按钮,然后重新刷新浏览器,再点击stop
- 首先找到我们首屏渲染的入口函数
- 上面的时间节点调小,能够看到有 ./src/index.js,里面有个render,这里就是首次渲染的入口
- 整个render的调用栈就是首次渲染的调用流程
- 可以大体将这个流程和功能分为三个部分
- 从左到右的工作:调度器、协调器、渲染器
调度器 render
- 第一部分:创建根fiber节点
- 这里有这样一个函数:createFiber
- 我们来打个断点看看 createFiber 是不是创建了根fiber节点:FiberNode
- 这里是 createFiber 声明的地方,其他地方都是调用
- 刷新页面之后,我们能够进入到函数里面
- 能够看到函数参数的值
- tag:3是什么意思? 从右边调用栈中看他的上层函数
- 发现传入的3是 HostRoot,所以createHostRootFiber就是创建 FiberNode 的函数
- 觉得少了点啥,唯一的根Fiber节点由谁创建的?current又在哪儿?
- 看下面的代码:
- new FiberRootNode(containerInfo, tag, hydrate)创建了 FiberRootNode
- root.current = uninitializedFibe;FiberRootNode的current 指向 FiberNode
这回,根Fiber节点的准备就完成了,接下来会进行首屏渲染,渲染到页面上。
- 16版本里面的unbatchedUpdates更改为下面红框中的,太长了不打了,哈哈哈哈
- 再下面是scheduleUpdateOnFiber:这里就是调度这次更新。
- 调度成功之后就会执行这次更新,从根节点执行这次更新,如下图的函数就是执行更新。
- 创建workInProgress的流程分为递、归两个阶段
- 递阶段是beginWork,归阶段是completeWork
- 至此,整个renderRootSync的执行就是协调器的执行
- 协调器被执行的阶段称为render阶段
- 渲染器工作流程被称为commit阶段
- 渲染器的工作主要目的:将变化的阶段渲染到视图上
总结
render阶段是如何工作的,这些工作都有哪些重要函数做配合。接下来会具体说这些函数都做了些什么,与我们的Fiber树做对应。
下一篇会先来讲解JSX,从这里入手,到render阶段。感谢大家支持~~
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END