React18原理: React核心对象之ReactElement对象和Fiber对象

【React】最新版本18 源码遨游(一) createElement() React源码遨游 今天新开的专栏主要围绕着React源码进行学习,切入口主要围绕着React的顶层API(即React)。 createElement() createElment() 隶属于顶层ApiReact的 /src/ReactElement.js中。 首先我们看一下创建组件的代码,然后逐句分析一下。 export function createElement(type, config, children) { let propName; // Reserved names are ex 阅读详情

React中的核心对象

  • 在React应用中,有很多特定的对象或数据结构.了解这些内部的设计,可以更容易理解react运行原理
  • 列举从react启动到渲染过程出现频率较高,影响范围较大的对象,它们贯穿整个react运行时
    • 如 ReactElement 对象
    • 如 Fiber 对象
  • 其他过程的重要对象
    • 如事件对象(位于react-dom/events保障react应用能够响应ui交互)
    • 如 ReactContext, ReactProvider, ReactConsumer对象等

ReactElement对象

  • 入口函数 ReactDOM.render(<App />, document.getElementByld('root');

  • 可以简单的认为,包括 <App/> 及其所有子节点都是ReactElement对象(在render之后才会生成子节点)

  • 每个ReactElement对象的区别在于type不同,其type定义在shared包中

  • 所有采用jsx语法书写的节点,都会被编译器转换,最终会以React.createElement(..)的方式

  • 创建出来一个与之对应的ReactElement对象

  • ReactElement对象的数据结构如下,定义在: packages/shared/ReactElementType.js

    /**
     * Copyright (c) Meta Platforms, Inc. and affiliates.
     *
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
     *
     * @flow
     */
    
    export type ReactElement = {
      $$typeof: any,
      type: any,
      key: any,
      ref: any,
      props: any,
      // ReactFiber
      _owner: any,
    
      // __DEV__
      _store: {validated: boolean, ...},
    };
    
  • 特别关注 key 和 type 这两个属性

    • key 属性在reconciler阶段会用到
      • 所有的ReactElement对象都有key属性
      • 且其默认值是null
      • 后续在diff算法中会使用到
    • type 属性决定了节点的种类
      • 它的值可以是字符串(代表div,span等dom节点),函数(代表function,class等节点)
      • 或者react内部定义的节点类型(portal,context,fragment等)
      • 在reconciler阶段,会根据type执行不同的逻辑
        • 如type是一个字符串类型,则直接使用.
        • 如type是一个ReactComponent类型,则会调用其render方法获取节点.
        • 如type是一个function类型,则会调用该方法获取子节点
  • ReactElement 的工厂方法如下,定义在:packages/react/src/ReactElementProd.js

    /**
     * Factory method to create a new React element. This no longer adheres to
     * the class pattern, so do not use new to call it. Also, instanceof check
     * will not work. Instead test $$typeof field against Symbol.for('react.element') to check
     * if something is a React Element.
     *
     * @param {*} type
     * @param {*} props
     * @param {*} key
     * @param {string|object} ref
     * @param {*} owner
     * @param {*} self A *temporary* helper to detect places where `this` is
     * different from the `owner` when React.createElement is called, so that we
     * can warn. We want to get rid of owner and replace string `ref`s with arrow
     * functions, and as long as `this` and owner are the same, there will be no
     * change in behavior.
     * @param {*} source An annotation object (added by a transpiler or otherwise)
     * indicating filename, line number, and/or other information.
     * @internal
     */
    function ReactElement(type, key, ref, owner, props) {
      const element = {
        // This tag allows us to uniquely identify this as a React Element
        $$typeof: REACT_ELEMENT_TYPE,
    
        // Built-in properties that belong on the element
        type: type,
        key: key,
        ref: ref,
        props: props,
    
        // Record the component responsible for creating this element.
        _owner: owner,
      };
    
      if (__DEV__) {
        // The validation flag is currently mutative. We put it on
        // an external backing store so that we can freeze the whole object.
        // This can be replaced with a WeakMap once they are implemented in
        // commonly used development environments.
        element._store = {};
    
        // To make comparing ReactElements easier for testing purposes, we make
        // the validation flag non-enumerable (where possible, which should
        // include every environment we run tests in), so the test framework
        // ignores it.
        Object.defineProperty(element._store, 'validated', {
          configurable: false,
          enumerable: false,
          writable: true,
          value: false,
        });
        // debugInfo contains Server Component debug information.
        Object.defineProperty(element, '_debugInfo', {
          configurable: false,
          enumerable: false,
          writable: true,
          value: null,
        });
        if (Object.freeze) {
          Object.freeze(element.props);
          Object.freeze(element);
        }
      }
    
      return element;
    }
    
  • 举一个App组件的例子

    class App extends React.Component {
      render() {
        return (
          <div className="app">
            <header>header</header>
            <Content />
            <footer>footer</footer>
          </div>
        )
      }
    }
    
    class Content extends React.Component {
      render() {
        return (
          <React.Fragment>
            <p>1</p>
            <p>2</p>
            <p>3</p>
          </React.Fragment>
          );
        }
    }
    
    export default App;
    
  • 这个代码,对应着 ReactElement 树结构如下

  • class和function类型的组件,其子节点是在render之后(reconciler阶段)才生成的
  • 此处只是单独表示 ReactElement 的数据结构
  • 父级对象和子级对象之间是通过props.children属性进行关联的(与fiber树不同)
  • ReactElement虽然不能算是一个严格的树,也不能算是一个严格的链表
    • 它的生成过程是自顶向下的,是所有组件节点的总和
    • ReactElement树(暂且用树来表述)和fiber树是以props.children为单位先后交替生成的
    • 当ReactElement树构造完毕,fiber树也随后构造完毕
  • reconciler阶段会根据ReactElement的类型生成对应的fiber节点
    • 注意,不是一一对应
    • 比如,Fragment类型的组件在生成fiber节点的时候会略过

Fiber对象

  • react-reconciler包是react应用的中枢

  • 连接渲染器(react-dom)和调度中心(scheduler),同时自身也负责fiber树的构造

  • 先看数据结构,其type类型的定义在 ReactInternalTypes.js 中

    // A Fiber is work on a Component that needs to be done or was done. There can
    // be more than one per component.
    export type Fiber = {
      // These first fields are conceptually members of an Instance. This used to
      // be split into a separate type and intersected with the other Fiber fields,
      // but until Flow fixes its intersection bugs, we've merged them into a
      // single type.
    
      // An Instance is shared between all versions of a component. We can easily
      // break this out into a separate object to avoid copying so much to the
      // alternate versions of the tree. We put this on a single object for now to
      // minimize the number of objects created during the initial render.
    
      // Tag identifying the type of fiber.
      tag: WorkTag,
    
      // Unique identifier of this child.
      key: null | string,
    
      // The value of element.type which is used to preserve the identity during
      // reconciliation of this child.
      elementType: any,
    
      // The resolved function/class/ associated with this fiber.
      type: any,
    
      // The local state associated with this fiber.
      stateNode: any,
    
      // Conceptual aliases
      // parent : Instance -> return The parent happens to be the same as the
      // return fiber since we've merged the fiber and instance.
    
      // Remaining fields belong to Fiber
    
      // The Fiber to return to after finishing processing this one.
      // This is effectively the parent, but there can be multiple parents (two)
      // so this is only the parent of the thing we're currently processing.
      // It is conceptually the same as the return address of a stack frame.
      return: Fiber | null,
    
      // Singly Linked List Tree Structure.
      child: Fiber | null,
      sibling: Fiber | null,
      index: number,
    
      // The ref last used to attach this node.
      // I'll avoid adding an owner field for prod and model that as functions.
      ref:
        | null
        | (((handle: mixed) => void) & {_stringRef: ?string, ...})
        | RefObject,
    
      refCleanup: null | (() => void),
    
      // Input is the data coming into process this fiber. Arguments. Props.
      pendingProps: any, // This type will be more specific once we overload the tag.
      memoizedProps: any, // The props used to create the output.
    
      // A queue of state updates and callbacks.
      updateQueue: mixed,
    
      // The state used to create the output
      memoizedState: any,
    
      // Dependencies (contexts, events) for this fiber, if it has any
      dependencies: Dependencies | null,
    
      // Bitfield that describes properties about the fiber and its subtree. E.g.
      // the ConcurrentMode flag indicates whether the subtree should be async-by-
      // default. When a fiber is created, it inherits the mode of its
      // parent. Additional flags can be set at creation time, but after that the
      // value should remain unchanged throughout the fiber's lifetime, particularly
      // before its child fibers are created.
      mode: TypeOfMode,
    
      // Effect
      flags: Flags,
      subtreeFlags: Flags,
      deletions: Array<Fiber> | null,
    
      // Singly linked list fast path to the next fiber with side-effects.
      nextEffect: Fiber | null,
    
      // The first and last fiber with side-effect within this subtree. This allows
      // us to reuse a slice of the linked list when we reuse the work done within
      // this fiber.
      firstEffect: Fiber | null,
      lastEffect: Fiber | null,
    
      lanes: Lanes,
      childLanes: Lanes,
    
      // This is a pooled version of a Fiber. Every fiber that gets updated will
      // eventually have a pair. There are cases when we can clean up pairs to save
      // memory if we need to.
      alternate: Fiber | null,
    
      // Time spent rendering this Fiber and its descendants for the current update.
      // This tells us how well the tree makes use of sCU for memoization.
      // It is reset to 0 each time we render and only updated when we don't bailout.
      // This field is only set when the enableProfilerTimer flag is enabled.
      actualDuration?: number,
    
      // If the Fiber is currently active in the "render" phase,
      // This marks the time at which the work began.
      // This field is only set when the enableProfilerTimer flag is enabled.
      actualStartTime?: number,
    
      // Duration of the most recent render time for this Fiber.
      // This value is not updated when we bailout for memoization purposes.
      // This field is only set when the enableProfilerTimer flag is enabled.
      selfBaseDuration?: number,
    
      // Sum of base times for all descendants of this Fiber.
      // This value bubbles up during the "complete" phase.
      // This field is only set when the enableProfilerTimer flag is enabled.
      treeBaseDuration?: number,
    
      // Conceptual aliases
      // workInProgress : Fiber ->  alternate The alternate used for reuse happens
      // to be the same as work in progress.
      // __DEV__ only
    
      _debugInfo?: ReactDebugInfo | null,
      _debugOwner?: Fiber | null,
      _debugIsCurrentlyTiming?: boolean,
      _debugNeedsRemount?: boolean,
    
      // Used to verify that the order of hooks does not change between renders.
      _debugHookTypes?: Array<HookType> | null,
    };
    
    • fiber.tag
      • 表示fiber类型,根据 ReactElement 组件的type进行生成,在react内部共定义了25种tag
    • fiber.key
      • ReactElement 组件的key一致
    • fiber.elementType
      • 一般来讲和ReactElement组件的type一致
    • fiber.type
      • 一般来讲和fiber.elementType一致.一些特殊情形下,比如在开发环境下为了兼容热更新 (HotReloading)
      • 会对 function, class, ForwardRef类型的 ReactElement做一定的处理
      • 这种情况会区别于fiber.elementType
    • fiber.stateNode
      • 与fiber关联的局部状态节点
      • 比如:HostComponent 类型指向与fiber节点对应的dom节点
      • 根节点 fiber.stateNode 指向的是 FiberRoot
      • class 类型节点其 stateNode 指向的是 class 实例
    • fiber.return
      • 指向父节点
    • fiber.child
      • 指向第一个子节点
    • fiber.sibling
      • 指向下一个兄弟节点
    • fiber.index
      • fiber在兄弟节点中的索引,如果是单节点默认为0.
    • fiber.ref
      • 指向在ReactElement组件上设置的ref
      • string类型的ref除外,这种类型的ref已经不推荐使用
      • reconciler阶段会将string类型的ref转换成一个function类型
    • fiber.pendingProps
      • 输入属性,从 ReactElement对象传的props
      • 用于和 fiber.memoizedProps 比较可以得出属性是否变动
    • fiber.memoizedProps
      • 上一次生成子节点时用到的属性,生成子节点之后保持在内存中
      • 向下生成子节点之前叫做pendingProps
      • 生成子节点之后会把pendingProps赋值给 memoizedProps用于下一次比较
      • pendingProps和memoizedProps比较可以出属性是否变动
    • fiber.updateQueue
      • 存储update更新对象的队列,每一次发起更新,都需要在该队列上创建一个update对象
    • fiber.memoizedState
      • 上一次生成子节点之后保持在内存中的局部状态
    • fiber.dependencies
      • 该fiber节点所依赖的(contexts, events)等
    • fiber.mode
      • 二进制位 Bitfield, 继承至父节点,影响本fiber节点及其子树中所有节点
      • 与react应用的运行模式有关(有ConcurrentMode, NoMode等选项)
    • fiber.flags
      • 标志位,副作用标记(在16.x版本中叫做effectTag)
      • 在 ReactFiberFlags.js中定义了所有的标志位
      • reconciler阶段会将所有拥有flags标记的节点添加到副作用链表中,等待commit阶段的处理
    • fiber.subtreeFlags
      • subtreeFlags是一个二进制形式的属性,它代表了Fiber节点子树的操作依据
      • 换句话说,它包含了有关该节点及其所有子节点的更新信息。这是React内部用于优化和协调更新的重要机制之一
      • 具体来说,subtreeFlags可能包含各种标志,这些标志指示了哪些子节点需要更新、哪些操作正在进行中、哪些操作已经完成等
      • React使用这些标志来有效地管理组件的更新过程,确保只更新实际发生变化的部分,从而提高性能和效率
      • 需要注意的是,subtreeFlags是React内部使用的属性,对于大多数开发者来说,通常不需要直接与之交互
      • React的公开API和抽象层使得开发者可以专注于编写组件逻辑,而无需关心底层的更新和渲染机制
    • fiber.deletions
      • 存储将要被删除的子节点.默认未开启,
    • fiber.nextEffect
      • 单向链表,指向下一个有副作用的fiber节点
    • fiber.firstEffect
      • 指向副作用链表中的第一个fiber节点
    • fiber.lastEffect
      • 指向副作用链表中的最后一个fiber节点.
    • fiber.lanes
      • 本fiber节点所属的优先级,创建fiber的时候设置
    • fiber.childLanes
      • 子节点所属的优先级
    • fiber.alternate
      • 指向内存中的另一个fiber,每个被更新过fiber节点在内存中都是成对出现(current 和 workInProgress)

  • 绘制与ReactElement对应的一棵Fiber树
  • 这里的fiber树只是为了和上面的ReactElement树对照
  • 其中 <App/>, <Content/> 为ClassComponent类型的fiber节点
  • 其余节点都是普通 HostComponent 类型节点
  • <Content/> 的子节点在ReactElement树中是React.Fragment
  • 但是在 fiber 树中 React.Fragment并没有与之对应的fiber节点
  • reconciler阶段对此类型节点做了单独处理
  • 所以ReactElement节点和fiber节点不是一对一匹配
【React】React18核心源码解读 阅读详情

相关推荐

JSX不是语法糖:React编译机制与 createElement 契约解析

JSX 是 React 的声明式标记语法,其本质是构建 React Element 对象的编译时契约,而非运行时 HTML 或字符串模板。它依赖 Babel 等工具在构建阶段严格转换为 React.createElement 调用,该函数接收 type、props 和 children 三类参数,共同构成可被协调器(reconciler)比对的描述性对象树。这一机制决定了组件挂载、更新与卸载的底层行为,直接影响状态一致性、列表渲染正确性(如 key 设计)、条件渲染逻辑(如 0 与 falsy 的区别)及服

weixin_30940783的博客 344

ReactElement

React系列(2) ReactElement React.createElement做了什么 先判断config中内置props(key,ref,self,source)存在且有效,则赋值给新声明的变量 再将config中非内置的props 给新声明的props(key和ref不会跟其他config中的变量一起被处理,而是单独作为变量出现在ReactElement上。) 判断如果孩子节点为一个...

qq_42843126的博客 2064

React面试备考指南:从258题拆解到核心原理

React作为前端主流框架,其面试考察早已从单一API记忆转向对运行原理与工程实践的深度理解。理解JSX编译链路、Fiber协调机制、setState批处理逻辑以及Hooks闭包陷阱,是应对高难度问题的关键。这些原理不仅有助于性能优化与复杂状态管理,还能在搜索防抖、大列表渲染、组件设计等真实场景中从容决策。随着React 19与RSC的普及,面试也开始关注服务端组件、并发特性及AI辅助开发下的代码质量把控。本文基于一份258题高频题库的拆解,梳理从基础API到源码原理的分层复习路径,分享“问题拆解法”与答案

weixin_33845881的博客 399

在 React 中元素(Element)和组件(Component)的区别

在 React 中,元素是构成 React 应用的基本构建块。一个 React 元素是一个描述用户界面上某个部分的对象,它定义了应该显示什么内容以及如何显示。元素是不可变的,一旦创建就无法更改。</h1>;在这个例子中,<h1>标签代表一个 React 元素,描述了一个带有文本 “Hello, world!” 的标题。元素:元素是 React 的基本构建块,代表 UI 的某一部分。你可以将元素直接渲染到 DOM 中。组件:组件是可以复用的 UI 单元,通常包含逻辑和状态。

My_wife_QBL的博客 2075

基于NXP BFU730F的宽带WiFi LNA设计:从原理到实测的完整指南

低噪声放大器(LNA)是无线通信接收链路中的关键器件,其性能直接决定了系统的接收灵敏度。LNA的核心原理是在放大微弱信号的同时,尽可能降低自身引入的噪声,并保持良好的线性度以应对强干扰。在宽带应用场景下,如覆盖2.4GHz至5.9GHz的现代WiFi系统,设计需在宽带匹配、噪声优化和增益平坦度之间取得精妙平衡。本文以NXP的BFU730F SiGe:C HBT晶体管为核心,深入解析一种采用电阻反馈和LC匹配网络的经典宽带LNA架构。该设计通过优化反馈网络,在宽达3.5GHz的频带内实现了优异的噪声系数(低至

weixin_33587161的博客 329

voc与txt互转

voc2txt # coding:utf-8 from __future__ import print_function import os import random import glob import xml.etree.ElementTree as ET def xml_reader(filename): """ Parse a PASCAL VOC xml file """ tree = ET.parse(filename) size = tree.find('siz

weixin_44898889的博客 826

React Element介绍

React Element是React中的核心概念之一,它代表了React应用中的UI元素。React Element并不是真实的DOM节点,而是一个轻量级的、不可变的、描述性的对象,它包含了创建UI所需的类型(type)、属性(props)和子元素(children)等信息。React使用React Element来构建UI,并在内部通过虚拟DOM(Virtual DOM)来优化真实的DOM更新。

qq_39237831的博客 944

基于STM32与毫米波雷达的非接触式睡眠监测系统

物联网和嵌入式系统技术正在推动医疗健康设备的智能化发展。通过传感器网络采集生理信号,结合信号处理算法实现健康监测已成为主流技术方案。毫米波雷达凭借其非接触检测特性,在呼吸、心率等生命体征监测中展现出独特优势。STM32系列MCU凭借丰富外设和低功耗特性,成为医疗级嵌入式设备的首选平台。本系统整合60GHz毫米波雷达、红外测温与无线传输模块,构建了完整的睡眠质量评估解决方案,其硬件架构设计、信号处理算法和低功耗优化策略对可穿戴医疗设备开发具有参考价值。

weixin_36369848的博客 614

挑战一篇文章通俗易懂讲清楚 React Element、React Component、JSX、Fiber 以及 Diff 算法的概念及其相互关系

挑战一篇文章通俗易懂讲清楚 React Element、React Component、JSX、Fiber 以及Diff算法的概念及其相互关系,React 源码学习笔记

weixin_48191864的博客 1157

CCS20实战入门:第一个工程搭建示例

通过实际操作演示如何在ccs20中创建并配置首个开发项目,涵盖环境设置与基础调试步骤,帮助新手快速上手ccs20集成开发环境,提升嵌入式开发效率。

weixin_31185473的博客 888

5GCPE与4G物联网卡兼容实战:通过AT指令修改IMEI实现设备迁移

本文详细介绍了如何通过AT指令修改5GCPE设备的IMEI,实现4G物联网卡的设备迁移。从硬件准备、驱动安装到串口工具配置,再到具体的AT指令操作步骤,提供了全面的实战指南。文章还包含信号优化、APN设置等实用技巧,帮助用户顺利完成设备迁移并提升网络性能。

weixin_28684757的博客 640

【React】React18.2.0核心源码解读

【React】React18.2.0核心源码解读

owo_ovo的博客 4232

电赛经验分享——赛前准备

⏩ 大家好哇!我是小光,想要成为系统架构师的嵌入式爱好者。⏩在之前的电赛中取得了省一的成绩,本文对电赛比赛前需要准备什么做一个经验分享。加入小光嵌入式交流群(qq群号:737327353)免费获取博主所有资料哦!

qq_52608074的博客 7781

React源码揭秘 | 启动入口

本文主要介绍React18版本的初始化启动过程,包含ReactElement元素的创建,createRoot如何创建根节点,以及Fiber树的基本结构,算是揭秘React核心原理的前置知识总结。

weixin_40710412的博客 1320

SAP_MM模块采购订单显示含税价&不含税简介

不含税价(Net Price):基础商品价格,不包含税金。含税价(Gross Price):基础价格加上适用税金后的总价。在SAP中,采购订单通常以不含税价为基础,通过配置税码和定价方案,系统会自动计算含税总价。

我小时候很黑的博客 2304

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【从0实现React18】 (三) 初探reconciler 带你初步探寻React的核心逻辑

Reconciler使React核心逻辑所在的模块,中文名叫,协调(reconciler)就是的意思。

m0_74989367的博客 1330

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

React源码阅读指南:从虚拟DOM到Fiber架构

虚拟DOM是现代前端框架的核心技术,通过内存中的轻量级表示实现高效的DOM更新。其工作原理是构建组件树的虚拟表示,通过Diff算法计算出最小变更集,最终批量更新真实DOM。React在此基础上引入Fiber架构,将渲染工作拆分为可中断的单元,配合Scheduler实现时间切片,大幅提升复杂应用的响应能力。这种设计尤其适合需要频繁更新的大型应用,如数据看板或交互式编辑器。通过深入React源码,开发者不仅能掌握虚拟DOM和Fiber的实现细节,还能学习到Facebook工程师如何设计高性能的调和(Reconc

weixin_32822843的博客 145

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Fiber 节点 —— 一个数据结构如何承载整个 React 运行时

React通过 Fiber 节点去承载整个 React 的运行时,今天我们通过这篇文章来梳理一下 React 是如何做的,为什么要这样做,这样做背后的考量是什么?

u011397689的博客 190

React 源码该从哪里开始看?先别急着啃 Fiber(工业级避坑指南)

《React源码阅读的正确路径:从宏观模型到微观实现》摘要:阅读React源码失败的主因在于缺乏整体认知框架。React本质是一个UI异步调度操作系统,核心包含描述UI、计算变化和执行更新三个环节。理解源码必须建立五大核心模型:ReactElement静态说明书、Fiber执行单元、Lane优先级控制、双缓存机制及Effect标签系统。源码阅读应聚焦react、react-reconciler和scheduler三个核心包,重点把握主流程而非细节优化。Fiber链表结构实现了可中断渲染,Hooks依赖Fib

2201_75368691的博客 403

react源码解析5.jsx&核心api

react源码解析5.jsx&核心api 视频讲解(高效学习):进入学习 往期文章: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命周期 12.状态更新流程 13.hooks源码 14.手写hooks 15.scheduler&Lane 16.concurrent模式

weixin_59558923的博客 104

【React源码】(十八)React 算法之调和算法

本节介绍了 React 源码中,fiber构造循环阶段用于生成下级子节点的函数(函数中的算法被称为调和算法), 并演示了可迭代节点比较的图解示例. 该算法十分巧妙, 其核心逻辑把newChildren序列分为 2 步遍历, 先遍历公共序列, 再遍历非公共部分, 同时复用oldFiber序列中的节点....

weixin_44828588的博客 446

从源码层面理解 React 是如何做 diff 的

大家好,我是前端西瓜哥。今天带带大家来分析 React 源码,理解它的单节点 diff 和多节点 diff 的具体实现。React 的节点对比逻辑是在 reconcileChildFibers 方法中实现的。reconcileChildFibers 是 ChildReconciler 方法内部定义的方法,通过调用 ChildReconciler 方法,并传入一个 shouldTrackSideEffects 参数返回。这样做是为了根据不同使用场景 ,产生不同的效果。因为一个组件的更新和挂载的流程不同的。比如

fe_watermelon的博客 564

Tendermint Core RPC 规范完全指南:JSON-RPC 端点、HTTP/WebSocket 调用与实现剖析

本指南系统梳理 Tendermint Core 的 RPC 规范(spec/rpc/README.md),涵盖 JSON-RPC 2.0 协议支持矩阵、RFC3339Nano 时间戳约定,以及健康检查、区块、交易、ABCI 与证据等全部端点的方法名、参数、HTTP/JSONRPC 请求方式与响应结构。读完本文,你将能直接使用 curl 或任意 JSON-RPC 客户端调用 Tendermint 节

gitblog_00735的博客 402

React项目如何使用Element ui?

初次在react项目中使用element框架,碰到了一些很简单的问题,但是卡了很久才解决,写篇博客记录一下。 1、安装: 在项目目录下下载: npm i element-react --save npm install element-theme-default --save 注:element官网快速上手中有提到 2、全局引用 在项目跟录下的index.js中全局引入 3、在项目中引用你需要的element组件 可能会报错 解决方式:在项目中下载依赖npm install react-hot-loa

果冻 1万+
上一篇: Vue2源码梳理:update的整体实现流程
下一篇: 前端架构: 脚手架框架之yargs的11种基础核心特性的应用教程
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值