当前位置: 首页 > news >正文

React底层原理

一句话总结:

  • React = 组件化 + 声明式 UI + 单向数据流,通过虚拟 DOM、Diff、Fiber 调度与批处理,把不可预测的 DOM 更新过程变成可预测、可中断、可优化的渲染流水线。

核心理念

  • 组件化: UI 拆分为可复用的组件,组件由 propsstate 决定输出。
  • 声明式 UI: 你描述“界面应该是怎样的”,React 负责“如何更新到这个样子”。
  • 单向数据流: 数据从父到子流动,便于推理与调试。
  • 最小可变性: 尽量用不可变数据(便于浅比较和跳过渲染,即如果引用没有变化,则React 会直接复用已有 Fiber 和 DOM)与纯函数思想,减少副作用。

工作机制(从输入到界面)

  1. 触发更新: 调用 setState/useStateuseReducer 或父组件 props 变化。
  2. 调度与批处理: React 调度器对更新分优先级,可能合并多次更新(批处理)。
  3. 渲染阶段(计算):
    • 计算新的组件树(虚拟树),执行函数组件体,收集 hooks 调用结果。
    • 通过 Diff(协调)找出和上一次的差异,生成最小变更集。
  4. 提交阶段(应用):
    • 将差异一次性提交到真实 DOM(或原生宿主,如 React Native),触发必要的副作用。
    • 执行布局/副作用(如 useLayoutEffectuseEffect)。

原理要点

  • 声明式UI与组件化:

    • 声明式UI: 在 React 中,你只需要描述应用在给定状态下应该呈现的样子。当状态改变时,React 会自动计算出需要进行的更改,而不是手动操作DOM元素。
    • 组件化: 整个应用由独立的、可复用的组件构成,每个组件管理自己的状态(state)和属性(props)。这种模块化使得代码更易于管理和维护。
  • 虚拟 DOM(VNode/Element):
    虚拟DOM是一个轻量级的JavaScript对象树,它是真实DOM结构的一个内存表示。每次组件状态(state)发生变化时,React 会生成一个新的虚拟DOM树。它避免了直接、频繁地操作昂贵的真实DOM,从而提高了性能。

  • 协调机制 (Reconciliation) 与 Diff 算法:
    这是React高效更新的关键所在:

    • Diff 算法: React 会对比新旧两棵虚拟DOM树的差异。
      • 对比新旧 Fiber 树:
        • key 不变且 type 相同 → 复用节点,更新 props。
        • key 或 type 改变 → 卸载旧节点,创建新节点。
    • 高效更新: 通过一系列启发式算法(如比较相同位置的元素类型、使用 key 属性等),React 能够找出两棵树之间最小的差异集合(即需要更新的部分)。
    • 批量更新: 找到差异后,React 会将这些必要的更改批量应用到真实的DOM上,而不是逐个更新,从而最大限度地减少浏览器重排和重绘。
  • Fiber 架构与任务调度:
    从 React 16 开始,引入了 Fiber 架构:

    • 异步可中断更新: Fiber 架构将渲染任务拆分为多个小单元,并根据优先级进行调度。这意味着 React 可以在渲染过程中暂停工作,让浏览器处理更高优先级的任务(如用户输入、动画),然后再恢复渲染。这使得用户界面响应更流畅,改善了用户体验。
    • 优先级机制: 不同的更新可以有不同的优先级。例如,用户输入的响应优先级高于后台数据更新
什么是 React Fiber

Fiber 节点(Fiber node)本质上是一个普通的 JavaScript 对象。用于管理React 内部组件和DOM元素相关信息、调度更新工作的内部数据结构。

  • 定义: Fiber 是 React 16+ 引入的新的内部架构与数据结构(Fiber node),用于实现可中断、可恢复、分片的渲染与更细粒度的优先级调度。
  • 目标: 时间分片与可中断渲染、优先级调度(让高优先级交互优先)、更好地处理动画/交互、改进错误边界与异步渲染(Suspense)。
举例:

比如我有这么一个jsx,会有几个React Fiber?

<div><Content />
</div>funciton Content() {return <h1>你好</h1>
}

在这里插入图片描述

为什么需要 Fiber

Fiber 使用页面更新更流畅、响应速度更快,通过了更好的用户体验。 它将 React 的更新逻辑从一个不可控的、同步的“跑到底”过程,变成了一个可控的、可中断的、高优先级的智能调度系统,使得 React 应用在复杂场景下依然能保持高性能。

  • 经典递归渲染不可中断,遇到大树时会卡住主线程。
  • Fiber 将递归改为可中断的循环+链表结构,支持时间切片与调度,提升交互流畅度。
Fiber 节点(Fiber node)本质
  • 每个将要渲染的元素(DOM 节点或组件)对应一个 Fiber 节点。
  • 常见重要字段(简化理解):
    • type: 组件类型(函数/类)或内置标签字符串(如 'div')。
    • tag: 节点种类(函数组件、类组件、HostComponent等)。
    • pendingProps / memoizedProps: 本次待生效的 props / 上次生效的 props。
    • stateNode: 实例引用(类组件实例或真实 DOM 节点)。
    • child / sibling / return: 构成 Fiber 树的单向链表结构。
    • flags(旧称 effectTag): 标记需要在 commit 阶段执行的副作用。
    • lanes / priority: 更新优先级。
    • updateQueue: 挂起的状态更新队列(setState/useState 等)。

与你当前报错的关系

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.
Check the render method of ModalTrend. at createFiberFromTypeAndProps (react-dom.development.js:28478:1)

  • 报错栈里的 createFiberFromTypeAndProps 就是“根据 Element 的 typeprops 生成 Fiber”的入口之一。
  • 如果 JSX 里的组件未正确导入,type 会是 undefined,在创建 Fiber 时即抛错。你这里的 Modal/ModalHeader/ModalContent 就是典型案例。

常见面试/排障要点

  • 小写标签编译成 'div' 这类字符串 → HostComponent → Fiber 会创建 DOM 节点。
  • 大写标签编译成变量(函数/类)→ Function/ClassComponent → Fiber 会执行函数或实例化类。
  • 并发特性(Concurrent Rendering)不是并发线程,而是可中断/分片的合作式调度。
  • Suspense/Transition 基于 Fiber 的优先级与挂起机制工作。

如果你想更直观地观察 Fiber 行为,建议在开发工具中开启 “Highlight updates” 或使用 Profiler,能看到分片提交与优先级带来的差异。

http://www.dtcms.com/a/596479.html

相关文章:

  • tensorflow 图像分类 之四
  • GEO优化:针对生成式AI内容分发逻辑的四大维度优化策略
  • 做a手机视频在线观看网站网页程序开发采购
  • USP-Ulysses+Ring-Attention技术原理
  • mirage 接口mock 拦截
  • flash网站设计教程北京建设网上银行
  • 高端网站建设设计公司有哪些wordpress网站迁移后插件
  • redis进阶 - 底层数据结构
  • 【自然语言处理】语料库:自然语言处理的基石资源与发展全景
  • Rust: 量化策略回测与简易线程池构建、子线程执行观测
  • 基于systemd的系统负载控制与检测方案
  • 闲谈-三十而已
  • LangChain 是一个 **大语言模型(LLM)应用开发框架**
  • 从RAM/ROM到Redis:项目架构设计的存储智慧
  • 高中课程免费教学网站网页塔防游戏排行榜
  • Access导出带图表的 HTML 报表:技术实现详解
  • 郑州上海做网站的公司嘉兴网站建设有前途吗
  • 学习JavaScript进阶记录(二)
  • 优化用户体验的小点:乐观更新链路 双数据库查询
  • C++—list:list的使用及模拟实现
  • EasyExcel 与 Apache POI 版本冲突导致的 `NoSuchMethodError` 异常
  • WebServer04
  • 品牌网站建设技术网站搜索引擎优化诊断
  • 优秀企业网站设计WordPress评论楼层
  • 卡索(CASO)汽车调查:新能源时代如何精准度量用户体验?
  • 手动模拟Spring(简易版)
  • 蓝牙钥匙 第88次 蓝牙钥匙未来发展趋势篇:用户体验未来趋势深度解析
  • jmeter集群压测配置方法和注意事项
  • [笔记]SolidWorks转URDF 在rviz2中显示
  • 抖音商城店铺用户体验优化研究(开题报告)