读React源码前一定要知道的几个基础概念

一、Fiber工作模式

虽然React18的文档里已经找不到相应的介绍了,但是了解一下过往还是有必要的。在之前的版本中,React团队提供了多种渲染应用的方式,包括:NoMode、StrictMode、ConcurrentMode等。那为啥要提供这么多的模式呢?说实话我也不清楚(毕竟官网也没给出答案,即使是React团队在公开场合聊到过这样的话题,你也不能全信,这种事情只有他们自己最清楚),但是仔细想一下好像也能理解,为了更好的兼容以及调试组件。

举个例子,React17脚手架创建出来的项目,默认是采用StrictMode(严格模式)来渲染应用的,但是这个版本也被很多人吐槽,说是大型项目使用React来开发的话,会非常卡顿。其中的一个原因就是构建fiber树跟生成缓存dom树的过程是一气呵成的,当应用非常庞大,递归层级非常深,一帧里干不完,那当前帧的重绘、下一帧的交互事件就得靠后执行呗,所以用户会感觉卡,掉帧。

为了解决这个问题,React18做了很多改动,比如每次执行performUnitOfWork前,都会去判断当前帧是否还有剩余时间等一些操作。那这个时候问题就来了,如何全面的测试React18呢?这个时候,渲染模式(Mode)就起到了作用,我可以将这些渲染模式暴露给用户,并且通过贴心的文档告诉用户,哪些模式是稳定的,哪些模式是以后要发布的,但是目前还在测试阶段。

二、什么是Fiber

它其实就是一个对象,在业务上,它描述着虚拟DOM的所有信息。

三、什么是虚拟DOM

React框架里,所有的 标签写法 都会被babel转换为 React.createElement,这个方法返回的就是虚拟DOM。本质也是对象,信息如下:

javascript 复制代码
let vDom = {
    $$typeof: REACT_ELEMENT_TYPE,
    type,
    key,
    ref,
    props,
    _owner
}

四、Fiber与虚拟DOM之间的关系

fiber是虚拟DOM的另一种表现形式。

现在来思考一个问题,已经有虚拟DOM了,为什么还要fiber?

想要回答这个问题,就要思考React15与16之间的区别。因为我没用过15,所以只能通过查阅资料的方式来获取答案。终于在之前的文档里,我找到了答案:

React Fiber是对核心算法的一次重新实现

其实这一句话就够了,无需过多解读,毕竟框架是人家写的,人家就是要通过这种方式来重构。

五、Fiber由哪些常见的属性组成?

属性 说明 备注
tag 当前fiber的类型 枚举:FunctionComponent、ClassComponent、HostRoot等
elementType 表明当前标签的类型 枚举:REACT_ELEMENT_TYPE、REACT_PORTAL_TYPE等
type React.createElement 的第一个参数 --
key 当前fiber的唯一标识 --
mode 当前fiber的工作模式 当前应用的渲染模式
return 当前fiber的父节点引用 --
child 当前fiber的子节点的引用 --
sibling 当前fiber的兄弟节点的引用 --
alternate 当前fiber的类型 --

当然,上面只是列举了一部分属性,我是想说,fiber属性的含义是非常重要的,不了解他们,基本上React源码很难能够捋顺。而我列举出来的这些属性,它们不需要深层次的debug,这对你来说或许是一个正向的帮助。

六、Fiber是如何创建的?

每个fiber对象都是一个FiberNode的实例。FiberNode源码如下:

我们知道了它是由什么组成的,那它具体跟组件是什么关系呢?

请看下面的组件:

react 复制代码
import React from 'react';

class App1 extends React.Component {
    render(){
        return <div className = 'father'>
            <div className = 'child1'>1</div>
            <div className = 'child2'>2</div>
        </div>
    }
}

上面的组件对应的fiber关系如下:

七、什么是调和?

React官方的解释如下:

调和就是React进行diff的过程。

什么时候会触发diff呢?每次更新的时候都会触发diff算法。触发更新的几种方式:

  • ReactDOM.render、React.createRoot().render
  • this.setState
  • setHook
  • props的改变
  • Context上下文发生改变

最后

好啦,本期分享到这里就结束啦,如果你觉得还不错,欢迎 点赞+收藏+关注 3连支持,如果有没写到或者讲错的地方,也欢迎各位大佬在评论区里指出,我们下期再见啦~~

相关推荐
^^为欢几何^^9 分钟前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang13 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘41 分钟前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
北岛寒沫5 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
everyStudy5 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步6 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者6 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js