0%

已完成 0/29 关

教学模式

你可以随时调整。

此设置调整教师的教学方式,无需重新生成课程。

第 12 关 含代码 含表格 约 10 分钟

将 UI 视为树:渲染树与模块依赖树

将 UI 视为树:渲染树与模块依赖树

在计算机科学中,“树(Tree)”是最常见也最优雅的数据结构之一。浏览器使用 HTML 构建 DOM 树,使用 CSS 构建 CSSOM 树。而在 React 中,我们同样使用“树”的心智模型来理解组件之间的层级、依赖与生命周期。

本关作为“描述 UI”大章的收官总结,将带你站在全局俯瞰两棵至关重要的树:渲染树(Render Tree) 与 模块依赖树(Module Dependency Tree)。


1. 为什么将 UI 视为一棵树?

树由一个单一的 根节点(Root Node) 开始,分出许多 分支节点(Branch Nodes),最后终止于没有子节点的 叶子节点(Leaf Nodes)。

组件的嵌套关系天然符合树形结构:

  • 顶层是你的根组件(例如 App);
  • 中间层是布局与功能模块(如 Header、Feed、Sidebar);
  • 底层是基础 UI 元素(如 Avatar、Button、Icon)。

将 UI 视为树,可以帮助你:

  1. 排查数据流向:清楚地看到 props 是如何从树根顺着树枝流向树叶的;
  2. 分析重新渲染成本:当某个节点重新渲染时,理解其子树会发生什么;
  3. 优化打包体积:通过模块依赖树分析哪些代码会被打包进最终的 JS 文件中。

2. 渲染树(Render Tree)

渲染树表示的是在当前这一次特定渲染中,由 React 组件构成的层级结构。

示例分析

观察以下组件嵌套代码:

// App.js
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="灵感发电机" />
      <InspirationGenerator>
        <Copyright year={2026} />
      </InspirationGenerator>
    </>
  );
}

在这段代码中:

  • App 是顶层的根组件(Root Component);
  • App 直接渲染了 FancyText 和 InspirationGenerator;
  • InspirationGenerator 内部可能会渲染一个引言组件 Inspiration,并将 Copyright 作为子组件包裹其中。

整个渲染树结构如下:

       App (根)
      /   \
FancyText   InspirationGenerator
           /       \
     Inspiration   Copyright

渲染树只包含 React 组件,不关心原生 HTML 标签: 渲染树关注的是你自定义组件之间的组合关系。至于 Inspiration 内部返回的是 <div> 还是 <p>,这属于浏览器 DOM 树的职责,不影响组件渲染树的结构。

条件渲染会让渲染树动态变化

渲染树不是静态不变的蓝图,而是每次渲染时的动态快照。 如果某个分支通过条件判断返回了 null,那么在这一次渲染树中,那个子节点及其整棵子树就根本不会存在!


3. 模块依赖树(Module Dependency Tree)

除了组件渲染关系,你的项目还包含许多 .js 文件,它们通过 import 和 export 相互连接。表示 JavaScript 模块之间引用关系的树,叫做模块依赖树。

在模块依赖树中:

  • 节点是一个个真实的文件(Modules),不仅包括组件文件,还包括图片资源、工具函数库(如 utils.js)、样式表;
  • 边表示 import 依赖关系。

打包工具(Bundler)如何利用它?

当开发完成准备上线时,打包工具(如 Webpack、Vite)会从根模块开始扫描整棵模块依赖树:

  • 凡是在这棵树上被引用的文件,都会被打包进最终的发布代码中;
  • 如果你写了一个文件但没有任何地方 import 它,打包工具就会通过 Tree-shaking(摇树优化) 将其从最终代码中剔除,避免浪费用户的流量!

4. 渲染树与依赖树的直观对比

特性渲染树 (Render Tree)模块依赖树 (Module Dependency Tree)
节点代表什么React 组件实例磁盘上的代码文件(.js, .css, 静态资源)
关系代表什么谁渲染了谁(父子嵌套与 children)谁 import 了谁
变化频率随用户交互与条件状态动态更新代码编写完成后相对固定
核心指导价值状态提升、渲染性能排查、上下文通信构建优化、按需加载、打包体积分析

总结与“描述 UI”大章复盘

至此,你已经完成了 React 官方课程中关于 “描述 UI” 的全部核心页面! 让我们回顾这一路上建立的扎实心智模型:

  1. 组件是基石:大写开头、返回 JSX 的纯净 JavaScript 函数;
  2. 多文件模块化:利用默认导出与具名导出整洁拆分;
  3. JSX 严格规则:单根包裹、自闭合与驼峰命名;
  4. 花括号插值:随时连接 JavaScript 表达式与内联样式对象;
  5. Props 单向传递:从父到子的只读参数,利用 children 构建弹性容器;
  6. 条件与列表渲染:用原生的 if、三元与 map,为列表赋予唯一的 key;
  7. 纯函数准则:严禁在渲染时修改外部状态,确保组件可预测;
  8. UI 树架构:以树的视角洞察层级关系与更新机制。

在接下来的下一大章中,我们将进入令 React 真正生动鲜活的核心领地——添加交互(Adding Interactivity)!

下一站:响应事件:事件处理函数、传参与阻止冒泡 →
© 2026 React 官方教程