您的 React 应用正在成形,许多组件彼此嵌套。React 如何跟踪应用的组件结构?
React 和许多其他 UI 库将 UI 建模为树结构。将您的应用视为树结构有助于理解组件之间的关系。这种理解将帮助您调试未来的概念,如性能和状态管理。
您将学习
- React 如何“看待”组件结构
- 什么是渲染树以及它的用途
- 什么是模块依赖树以及它的用途
您的 UI 作为树结构
树是项目之间的一种关系模型,UI 通常使用树结构来表示。例如,浏览器使用树结构来模拟 HTML(DOM)和 CSS(CSSOM)。移动平台也使用树来表示它们的视图层次结构。
像浏览器和移动平台一样,React 也使用树结构来管理和建模 React 应用中组件之间的关系。这些树是理解数据如何流经 React 应用以及如何优化渲染和应用大小的有用工具。
渲染树
组件的一个主要特性是能够组合其他组件的组件。当我们 嵌套组件 时,我们引入了父组件和子组件的概念,其中每个父组件本身也可能是另一个组件的子组件。
当我们渲染一个 React 应用时,我们可以用一棵树来模拟这种关系,称为渲染树。
这是一个渲染励志名言的 React 应用。
import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; export default function App() { return ( <> <FancyText title text="Get Inspired App" /> <InspirationGenerator> <Copyright year={2004} /> </InspirationGenerator> </> ); }
从示例应用中,我们可以构建上面的渲染树。
树由节点组成,每个节点代表一个组件。App
、FancyText
、Copyright
等等都是我们树中的节点。
React 渲染树中的根节点是应用的 根组件。在本例中,根组件是 App
,它是 React 渲染的第一个组件。树中的每个箭头都从父组件指向子组件。
深入探讨
您会注意到在上面的渲染树中,没有提到每个组件渲染的 HTML 标签。这是因为渲染树只由 React 组件 组成。
React 作为一个 UI 框架,与平台无关。在 react.dev 上,我们展示了渲染到 Web 的示例,它使用 HTML 标记作为其 UI 原语。但 React 应用程序也可以渲染到移动或桌面平台,它们可能使用不同的 UI 原语,例如 UIView 或 FrameworkElement。
这些平台 UI 原语不是 React 的一部分。无论你的应用程序渲染到哪个平台,React 渲染树都可以提供对我们 React 应用程序的洞察。
渲染树表示 React 应用程序的单次渲染过程。通过 条件渲染,父组件可以根据传递的数据渲染不同的子组件。
我们可以更新应用程序以有条件地渲染励志名言或颜色。
import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; export default function App() { return ( <> <FancyText title text="Get Inspired App" /> <InspirationGenerator> <Copyright year={2004} /> </InspirationGenerator> </> ); }
在本例中,根据 inspiration.type
的值,我们可能会渲染 <FancyText>
或 <Color>
。每次渲染过程的渲染树可能都不同。
尽管渲染树在不同的渲染过程中可能会有所不同,但这些树通常有助于识别 React 应用程序中的*顶级*和*叶子组件*。顶级组件是最靠近根组件的组件,会影响其下方所有组件的渲染性能,并且通常包含最复杂的逻辑。叶子组件位于树的底部,没有子组件,并且经常被重新渲染。
识别这些类别的组件有助于理解应用程序的数据流和性能。
模块依赖树
在 React 应用程序中,可以用树来建模的另一种关系是应用程序的模块依赖关系。当我们将组件和逻辑拆分到不同的文件中时,我们就创建了JS 模块,我们可以在其中导出组件、函数或常量。
模块依赖树中的每个节点都是一个模块,每个分支表示该模块中的一个 import
语句。
如果我们以之前的 Inspirations 应用程序为例,我们可以构建一个模块依赖树,或简称为依赖树。
树的根节点是根模块,也称为入口文件。它通常是包含根组件的模块。
与同一个应用程序的渲染树相比,它们有相似的结构,但也有一些显著的区别
- 构成树的节点表示的是模块,而不是组件。
- 非组件模块(如
inspirations.js
)也表示在这棵树中。渲染树只封装组件。 Copyright.js
出现在App.js
下面,但在渲染树中,组件Copyright
出现在InspirationGenerator
的子级中。这是因为InspirationGenerator
接受 JSX 作为子组件属性,因此它将Copyright
渲染为子组件,但没有导入该模块。
依赖树有助于确定运行 React 应用程序所需的模块。在构建用于生产环境的 React 应用程序时,通常会有一个构建步骤,将所有必要的 JavaScript 打包到客户端。负责此操作的工具称为打包器,打包器将使用依赖树来确定应包含哪些模块。
随着应用程序的增长,通常打包大小也会增加。较大的打包大小对于客户端来说下载和运行成本很高。较大的打包大小可能会延迟 UI 的绘制时间。了解应用程序的依赖树可能有助于调试这些问题。
总结
- 树是表示实体之间关系的常用方式。它们通常用于对 UI 进行建模。
- 渲染树表示在单次渲染过程中 React 组件之间的嵌套关系。
- 通过条件渲染,渲染树在不同的渲染过程中可能会发生变化。根据不同的属性值,组件可能会渲染不同的子组件。
- 渲染树有助于识别顶级组件和叶子组件。顶级组件会影响其下方所有组件的渲染性能,叶子组件通常会频繁地重新渲染。识别它们有助于理解和调试渲染性能。
- 依赖树表示 React 应用程序中的模块依赖关系。
- 构建工具使用依赖树将必要的代码打包到应用程序中。
- 依赖树有助于调试导致绘制时间变慢的大型打包,并为优化打包代码提供机会。