iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React深入了解原理
  • 734
分享到

React深入了解原理

2024-04-02 19:04:59 734人浏览 八月长安
摘要

目录VDOM(虚拟dom)Fiber架构初始化渲染更新时render阶段commit阶段VDOM(虚拟dom) React和Vue都是基于vdom的前端框架。 WEB界面由DOM树来

VDOM(虚拟dom)

ReactVue都是基于vdom的前端框架

WEB界面由DOM树来构建,当其中一部分发生变化时,其实就是对应的某个节点发生了变化。

若一次操作中有十次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这十次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attach到DOM树上,再进行后续的操作。

用js对象模拟DOM节点的好处是:

  • 页面的更新可以先全部反映在js对象(虚拟DOM)上,精准的对比关心的属性,避免大量无谓的计算。等更新完成后,再将最终的js对象映射成真是的DOM,交由浏览器去绘制。
  • 为应用带来的跨平台的能力,不再仅仅局限于浏览器端。比如:React-Native、canvas等。
//虚拟dom对象
{
    type: 'div',
    props: {
        id: 'aaa',
        className: ['bbb', 'ccc'],
        onClick: function() {}
    },
    children: []
}

react中,jsx由babel转义再经过render后生成我们想要的VDOM(虚拟DOM)。

Fiber架构

react15的时候,和 vue 的渲染流程还是很像的,都是递归渲染 vdom,增删改 dom 就行。

但是因为状态管理的差异导致了架构的差异。react的setState会渲染整个vdom,而一个应用的所有 vdom 可能是很庞大的,计算量就可能很大。

浏览器里 js 计算时间太长是会阻塞渲染的,会占用每一帧的动画、重绘重排的时间,这样动画就会卡顿。

那能不能把计算量拆分一下,每一帧计算一部分,不要阻塞动画的渲染呢?

顺着这个思路,react 就改造为了 fiber 架构,目标是打断计算,分多次进行。

渲染的时候不要直接更新到 dom 了,只找到变化的部分,打个增删改的标记,创建好 dom,等全部计算完了一次性更新到 dom 就好了。

初始化渲染

根据 React Element 生成对应的 Fiber 树

1.根据 React Element 生成对应的 Fiber 树

首次执行ReactDOM.render 会创建fiberRoot 和 rootFiber。

  1. fiberRoot:整个应用的根节点(只能有一个)
  2. rootFiber:组件树的根节点(可以有多个)

2.根据组件返回的JSX在内存中依次创建Fiber节点,并连接在一起构建形成Fiber树,被称为workInProgress Fiber树。最后以 workInProgress 作为最新的渲染树,fiberRoot 的 current 指针指向 workInProgress 使其变为 current Fiber 树。到此完成初始化流程。

  1. workInProgress:正在内存中构建的 Fiber 树称为 workInProgress Fiber树。在一次更新中,所有的更新都是发生在 workInProgress 树上。在一次更新之后,workInProgress 树上的状态是最新的状态,那么它将变成 current 树用于渲染视图。
  2. current:正在视图层渲染的树叫做 current 树。

更新时

render阶段,创建 dom,打上增删改的 tag,等全部计算完之后,commit 阶段一次性更新到 dom。

render阶段

beginWork和completeWork阶段会循环最新的jsx生成的虚拟dom,通过对比虚拟dom和current Fiber树生成workinProgress Fiber树。

beginWork

创建本次循环主体的子Fiber节点

  • mount(首屏渲染)时创建子Fiber节点,并返回改新建节点;
  • update时若不满足复用条件,则与mount时一样创建新的子fiber节点,并diff出相应的effTag挂在FIber节点上,并返回该新建节点;
  • updata时若满足复用条件,且判断仍需处理其子节点的后代,则返回复用后的子Fiber节点
  • updata时若满足复用条件,且判断不需继续处理其子节点的后代,则直接返回null值;

completeWork

构建或更新DOM节点

  • 构建过程中,会自下而上将子节点插入到当前节点
  • 更新过程中,会计算DOM 节点的属性,一旦属性需要更新,会为DOM节点对应的workINProgress节点标记Update的effectTag

自下而上收集effectList,最终收集到root上

Diff到底是谁跟谁比?

Diff 是 vdom 和 current Fiber 对比,生成 workInProgressFiber

effectTag与effectList

render阶段不会真正操作dom,只会创建dom然后打个effectTag的增删改标记。commit阶段就根据标记来更新dom就可以了。

但是commit阶段要在遍历一次fiber来查找有effectTag的节点,更新dom吗?

当然没问题,但是显然很低效。完全可以把有 effectTag 的节点收集到一个链表里,然后 commit 阶段直接遍历这个链表就行了。这个链表叫做 effectList。

react 会在 commit 阶段遍历 effectList,根据 effectTag 来增删改 dom。

这个队列叫做 effectList。

commit阶段

render阶段找到变化的部分,创建dom,打上增删改的tag,等全部计算完之后,commit阶段一次性更新到dom。

before mutation阶段(执行DOM操作前)

遍历effectList,依次执行:

1.处理DOM节点渲染/删除后的autoFocus、blur逻辑

2.调用getSnapshotBeforeUpdate生命周期钩子

3.调度useEffect mutation阶段(执行DOM操作)

遍历 effectList 来更新 dom

layout阶段(执行DOM操作后)

因为这个阶段已经可以拿到布局信息了,会同步调用 useLayoutEffect 的回调函数。而且这个阶段可以拿到新的 dom 节点,还会更新下 ref。

到此这篇关于React深入了解原理的文章就介绍到这了,更多相关React原理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: React深入了解原理

本文链接: https://www.lsjlt.com/news/165622.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React深入了解原理
    目录VDOM(虚拟dom)Fiber架构初始化渲染更新时render阶段commit阶段VDOM(虚拟dom) react和vue都是基于vdom的前端框架。 web界面由DOM树来...
    99+
    2022-11-13
  • 深入理解React State 原理
    目录问题:setState 到底是同步还是异步的?类组件statesetState原理揭秘函数组件state问题:setState 到底是同步还是异步的? 如果对 React 底层有...
    99+
    2022-11-12
  • 深入理解React调度(Scheduler)原理
    目录异步调度时间分片异步调度原理总结异步调度 问题:由于对于大型的 React 应用,会存在一次更新,递归遍历大量的虚拟 DOM ,造成占用 js 线程,使得浏览器没有时间去做一些动...
    99+
    2022-11-13
  • 从原生JavaScript到React深入理解
    目录从头开始理解 React原生 JavaScript 和 DOMReact 的基础咱老百姓也能学会的 JSX从头开始理解 React 作者:Stéphane B&ea...
    99+
    2022-11-13
  • React Streaming SSR原理示例深入解析
    目录功能简介基本原理使用示例Streaming HTMLSelective Hydration降级逻辑JS 和 CSS 设置源码解析数据结构Segment Bou...
    99+
    2022-12-20
    React Streaming SSR React Streaming
  • React Diff原理深入分析
    目录Diffing 算法逐层比较对比同类型的组件元素对比同一类型的元素对子节点进行递归Keys在了解Diff前,先看下React的虚拟DOM的结构 这是html结构 <di...
    99+
    2022-11-12
  • 深入理解React Native核心原理(React Native的桥接(Bridge)
    在这篇文章之前我们假设你已经了解了React Native的基础知识,我们会重点关注当native和JavaScript进行信息交流时的内部运行原理。 主线程 在开始之前,我们需要知...
    99+
    2022-11-12
  • 深入了解vuex的实现原理
    当面试被问vuex的实现原理,你要怎么回答?下面本篇文章就来带大家深入了解一下vuex的实现原理,希望对大家有所帮助!关于vuex就不再赘述,简单回顾一下:当应用碰到多个组件共享状态时,简单的单向数据流很容易被破坏:第一,多个视图依赖于同一...
    99+
    2023-05-14
    javascript vuex
  • 怎样深入理解react
    这篇文章给大家介绍怎样深入理解react,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。理解ReactElement和ReactClass的概念首先让我们理解两个概念:ReactElem...
    99+
    2022-10-19
  • React框架核心原理全面深入解析
    目录前言第一章 基本概念第二章 createElement 函数第三章 render函数第四章 Concurrent Mode第五章 Fibers第六章 Render and Com...
    99+
    2022-11-16
    React框架的原理 React框架核心
  • 深入了解JavaSpringBoot自动装配原理
    目录自动装配原理SpringBootApplicationEnableAutoConfigurationAutoConfigurationImportSelector总结在...
    99+
    2022-11-13
  • 深入了解Android IO的底层原理
    目录前言一、应用层1. IO的分类1.1 缓冲和直接1.2 阻塞和异步2. IO流程二、sysCall系统调用三、虚拟文件系统1. VFS结构2. VFS中的缓存3. IO流程四、文...
    99+
    2022-11-13
  • React更新渲染原理深入分析
    目录ScheduleLegacy modeConcurrent mode时间切片任务的优先级获取最先处理的taskReconcile前置知识从jsx到dom双缓存fiber tree...
    99+
    2022-12-23
    React更新渲染 React更新 React渲染
  • React中Redux核心原理深入分析
    目录一、Redux是什么二、Redux的核心思想三、Redux中间件原理四、手写一个Redux总结一、Redux是什么 众所周知,Redux最早运用于React框架中,是一个全局状态...
    99+
    2022-11-16
    React使用Redux React Redux用法
  • 深入了解Spring控制反转IOC原理
    目录一、什么是Spring IOC容器二、IOC有哪些优点三、控制反转(IOC)有什么作用四、IoC和DI有什么区别五、Spring IoC的实现机制六、IoC支持哪些功能七、Bea...
    99+
    2022-11-13
    Spring控制反转IOC Spring控制IOC Spring IOC
  • 带你深入了解Vue.$nextTick(原理浅析)
    白话一点就是说,其实这是和JS当中的事件循环是息息相关的,就是Vue不可能对每一个数据变化都做一次渲染,它会把这些变化先放在一个异步的队列当中,同时它还会对这个队列里面的操作进行去重,比如你修改了这个数据三次,它只会保留最后一次。这些变化是...
    99+
    2023-05-14
    $nextTick 前端 Vue.js
  • HDFS原理深入理解
    1.HDFS概述   1)数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,因此迫切需要一种系统来管理多台机器上的文件,这就       是分布式文件管理系统。 2)是一种允许...
    99+
    2017-01-26
    HDFS原理深入理解
  • 深入了解javascript原型和原型链
    目录一、什么是原型二、prototype三、__proto__四、constructor五、实例与原型六、原型的原型七、原型链一、什么是原型 原型:每一个javascript对象(除...
    99+
    2022-11-12
  • 深入了解Go的interface{}底层原理实现
    目录1. interface{}初探2. eface3. iface4. 接口转化1. interface{}初探 Go是强类型语言,各个实例变量的类型信息正是存放在inter...
    99+
    2022-06-07
    GO interface
  • 深入了解Golang interface{}的底层原理实现
    目录前言interface数据结构ifaceeface总结前言 在 Go 语言没有泛型之前,接口可以作为一种替代实现,也就是万物皆为的 interface。那到底 interface...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作