React 架构之Render阶段

本篇文章学习React源码,根据每个阶段进行源码debugger学习。

这里提供如何在本地打debugger:github.com/sunkuangdon…

如有不明白的,请留言(映射我已经做好了,大家可以在 react/build/node_modules/react-dom/cjs/react-dom.development.js 文件中最上面log一下试试,看控制台是否能打印出来)。

这个也是本人自学的项目,之后可能会有备注,觉得不对的大家可以评论给我,或者在备注中说明,我会看到。

希望你的备注格式是:/* name: 指出错误 */,谢谢大家

源码目录结构

我们先来了解如下:

  • 源码的目录结构是如何划分的
  • 调度器、渲染器、协调器所在目录在哪儿

顶层目录

React源码的顶层目录分为三个文件夹:

image.png

根目录 
├── fixtures # 包含给贡献者准备的小型React测试项目
├── packages # 包含元数据(比如 package.json)和React项目中pack
age的源码
├── scripts  # 各种工具链的脚本,比如git、jest、eslint等
复制代码

首先我们关注packages文件夹内部:

  • react文件:里面有许多和平台无关的代码。
  • 比如 react.Children、react.Component、react.useState等等。(index.js中能看到)

image.png

  • scheduler文件:调度器相关的代码

image.png

  • react-reconciler文件:协调器相关代码

image.png

  • react-dom文件:渲染器相关代码
  • 根DOM操作相关的API都在这里

image.png

  • shared文件夹:公共方法的代码

image.png

  • react-reconclier文件夹:实验性的包
  • 虽然是实验性的,内部很多功能还未开放。但是他一边对接Scheduler,一边对接不同平台的Renender。

首屏渲染流程

我们先来看看浏览器调用栈中显示出的React架构样子:

  • 运行我们的a-react-demo项目,浏览器中打开调试工具进入Performance面板
  • 刚开始是一片空白,点击下面这个按钮,然后重新刷新浏览器,再点击stop

image.png

  • 首先找到我们首屏渲染的入口函数
  • 上面的时间节点调小,能够看到有 ./src/index.js,里面有个render,这里就是首次渲染的入口
  • 整个render的调用栈就是首次渲染的调用流程

image.png

  • 可以大体将这个流程和功能分为三个部分
  • 从左到右的工作:调度器、协调器、渲染器

image.png

调度器 render

  • 第一部分:创建根fiber节点

image.png

  • 这里有这样一个函数:createFiber

image.png

  • 我们来打个断点看看 createFiber 是不是创建了根fiber节点:FiberNode
  • 这里是 createFiber 声明的地方,其他地方都是调用

image.png

  • 刷新页面之后,我们能够进入到函数里面
  • 能够看到函数参数的值

image.png

  • tag:3是什么意思? 从右边调用栈中看他的上层函数
  • 发现传入的3是 HostRoot,所以createHostRootFiber就是创建 FiberNode 的函数

image.png

  • 觉得少了点啥,唯一的根Fiber节点由谁创建的?current又在哪儿?
  • 看下面的代码:
  • new FiberRootNode(containerInfo, tag, hydrate)创建了 FiberRootNode
  • root.current = uninitializedFibe;FiberRootNode的current 指向 FiberNode

image.png

这回,根Fiber节点的准备就完成了,接下来会进行首屏渲染,渲染到页面上。

  • 16版本里面的unbatchedUpdates更改为下面红框中的,太长了不打了,哈哈哈哈

image.png

  • 再下面是scheduleUpdateOnFiber:这里就是调度这次更新。

image.png

  • 调度成功之后就会执行这次更新,从根节点执行这次更新,如下图的函数就是执行更新。

image.png

  • 创建workInProgress的流程分为递、归两个阶段
  • 递阶段是beginWork,归阶段是completeWork

image.png

  • 至此,整个renderRootSync的执行就是协调器的执行
  • 协调器被执行的阶段称为render阶段
  • 渲染器工作流程被称为commit阶段

image.png

  • 渲染器的工作主要目的:将变化的阶段渲染到视图上

image.png

总结

render阶段是如何工作的,这些工作都有哪些重要函数做配合。接下来会具体说这些函数都做了些什么,与我们的Fiber树做对应。

下一篇会先来讲解JSX,从这里入手,到render阶段。感谢大家支持~~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享