读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连支持,如果有没写到或者讲错的地方,也欢迎各位大佬在评论区里指出,我们下期再见啦~~

相关推荐
gnip5 小时前
企业级配置式表单组件封装
前端·javascript·vue.js
一只叫煤球的猫6 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
excel7 小时前
Three.js 材质(Material)详解 —— 区别、原理、场景与示例
前端
掘金安东尼7 小时前
抛弃自定义模态框:原生Dialog的实力
前端·javascript·github
hj5914_前端新手11 小时前
javascript基础- 函数中 this 指向、call、apply、bind
前端·javascript
薛定谔的算法11 小时前
低代码编辑器项目设计与实现:以JSON为核心的数据驱动架构
前端·react.js·前端框架
Hilaku11 小时前
都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?
前端·javascript·css
yangcode11 小时前
iOS 苹果内购 Storekit 2
前端
LuckySusu11 小时前
【js篇】JavaScript 原型修改 vs 重写:深入理解 constructor的指向问题
前端·javascript
LuckySusu11 小时前
【js篇】如何准确获取对象自身的属性?hasOwnProperty深度解析
前端·javascript