[铁人赛 Day11] React 原始码的初见面 ——官方 codebase 指南

前言

为了更近一步理解平常使用的 useState, useEffect, memo...等机制的运作,我尝试下载了 React 的原始码,没想到初次见面就让人手足无措。幸好官方提供了一些给开源贡献者的指南,跟随着官方的文件,可以省下不少力气。

底下的内容会跟着 React 的文件,认识原始码的大致架构。并且附上 IDE 的截图,让各位更好地想像。

最上层的资料夹

packages 里包含了所有 React 专案内的 packages 的 metadata(例如:package.json)以及 source code( src 子目录)。

fixtures 里面包含了几个让贡献者可以使用的测试工具。

build 资料夹里面有专案 build 出来的东西。

其他的资料夹大部分是工具相关,贡献者通常不会需要处理到、或者遇到跟这些资料夹相关的议题。

注:有另一个名称相似的专案 https://github.com/reactjs/reactjs.org 放的是 React 相关的文件。放 Source code 的专案则是 https://github.com/facebook/react

(我的专案 build 不起来,所以少了其中一个资料夹。除了 build,顶层资料夹就是这些。)

https://ithelp.ithome.com.tw/upload/images/20210921/20140045WVuH1Scipn.png

抛出错误的方式与 Invariants 模组

React 专案使用 console.error 来表示警告,只有在开发环境中才会显示,在正式环境中则是完全看不见。如下图:

https://ithelp.ithome.com.tw/upload/images/20210921/20140045Cigh0dMCUL.png

你还可以使用专案里的  invariant 模组。当情境是 false 的时候,Invariant 就会被抛出。你可以把这个功能想像成在做一个断言(assertion)。如下图:

https://ithelp.ithome.com.tw/upload/images/20210921/20140045NGNqoKMnUO.png

与上面不同的是,Invariant 在开发与正式环境中都会运行,只是在正式环境中,error message 会被自动的替换成 error code 来避免对 byte size 的负面影响。

multiple packages

React 是一个 monorepo。在同一个 repo 中管理多的模组的好处在於,方便统一管理 depencency、版号、流程,以及因为东西都放在一起,大规模的重构时会更容易,这些模组间的改变也可以互相协调。

React Core 核心要素

React 的核心包含所有 top-level 的 API,仅仅包含那些定义元件所必须的 API,不包含演算法或者任何 platform-specific 的 code。这些 API 会被 React DOM 以及 React Native 元件二者使用。React core 的内容位於 packages/react :底下的截图中,可以看到一些眼熟的 export createElementComponentChildren ... etc。

https://ithelp.ithome.com.tw/upload/images/20210921/20140045oBhUn12kyd.png

顺着 import export 的路线往下追,可以找到一些关於这些 core API 如何运作的线索。

https://ithelp.ithome.com.tw/upload/images/20210921/20140045tOcRfSFO6H.png

Event System

React 运用了一个事件系统来调整原生的事件,减缓不同浏览器之间的差异。

https://ithelp.ithome.com.tw/upload/images/20210921/20140045OhdgOmI3Eo.png

Reconcilers

即使是差异极大的 renderers 例如 React DOM 与 React Native,也会需要使用许多相同逻辑。特别是 React 使用的 reconciliation algorithm 演算法也应该要尽可能地相似,让 declarative rendering, custom components, state, lifecycle methods, 跟 refs 的运作在不同平台上的运作前後一致。

不同的 renderers 所共有的 code,我们称呼这个部分叫做 reconciler。当一个更新例如 setState() 被触发的时候,reconciler 会去呼叫元件上的 render(),然後对他们进行 mount, update, unmount 这些动作。

Reconciler 听起来太抽象吗?请参考之前关於 reconciliation 的文章:https://ithelp.ithome.com.tw/articles/10268531/

Fiber Reconciler

fiber 是用来解决前一版 stack reconciler 内既有的问题,以及一些长期存在的错误。React 16 之後就成了预设的 reconciler。他的 source code 可以在 react-reconciler 中找到。

https://ithelp.ithome.com.tw/upload/images/20210921/20140045VyOKoFmIrg.png

小结论

看完这些介绍之後,大概可以抓到如果想要理解例如 React.memo 的处理,会需要查找的资料夹有 packages/react 关於 React.memo 的内容,以及 packages/react-reconciler` 当中,可能有对於比较 prevProps 和 nextProps 判断机制的描写。

Ref

https://reactjs.org/docs/codebase-overview.html

https://reactjs.org/docs/implementation-notes.html


<<:  【踩坑】animation 选单按钮动起来(复习篇)

>>:  [Day26] Angular 的四种 Binding

JavaScript入门 Day04_变数宣告

嘿各位,今天要说的是 JavaScript 的变数宣告 为什麽昨天说像变魔法呢~ 因为只要使用变数宣...

自动化 End-End 测试 Nightwatch.js 之踩雷笔记:上传档案

上传本机端的档案其实很简单,只是单纯的 setValue() 就好了。 browser.setVal...

【第二十三天 - DFS 题目分析】

先简单回顾一下,今天预计分析的题目: 112. Path Sum 题目连结:https://lee...

Day19 iPhone捷径-电池健康度

Hello 大家, 我今天看到疯先生有分享一个电池寿命的捷径, 今年13跟去年的12差别不大, 我一...

# 将影片转换成图片 - Day 11

将影片转换成图片 - Day 11 今天要完成的工作是将搜集到的影片或是照片转换成 YOLOV3 可...