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

相关推荐
上单带刀不带妹几秒前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
前端风云志2 分钟前
typescript结构化类型应用两例
javascript
杨进军21 分钟前
React 创建根节点 createRoot
前端·react.js·前端框架
ModyQyW36 分钟前
用 AI 驱动 wot-design-uni 开发小程序
前端·uni-app
说码解字42 分钟前
Kotlin lazy 委托的底层实现原理
前端
gnip1 小时前
总结一期正则表达式
javascript·正则表达式
爱分享的程序员1 小时前
前端面试专栏-算法篇:18. 查找算法(二分查找、哈希查找)
前端·javascript·node.js
翻滚吧键盘1 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js
vim怎么退出1 小时前
万字长文带你了解微前端架构
前端·微服务·前端框架
你这个年龄怎么睡得着的1 小时前
为什么 JavaScript 中 'str' 不是对象,却能调用方法?
前端·javascript·面试