将你的用户界面理解为一棵树

你的 React 应用正在形成,许多组件相互嵌套。React 如何跟踪应用的组件结构?

¥Your React app is taking shape with many components being nested within each other. How does React keep track of your app’s component structure?

React 和许多其他 UI 库将 UI 建模为树。将你的应用视为一棵树对于理解组件之间的关系很有用。这种理解将帮助你调试性能和状态管理等未来概念。

¥React, and many other UI libraries, model UI as a tree. Thinking of your app as a tree is useful for understanding the relationship between components. This understanding will help you debug future concepts like performance and state management.

你将学习到

  • React 如何 “看到” 组件结构

    ¥How React “sees” component structures

  • 渲染树是什么以及它有什么用处

    ¥What a render tree is and what it is useful for

  • 什么是模块依赖树以及它的用途

    ¥What a module dependency tree is and what it is useful for

你的用户界面就像一棵树

¥Your UI as a tree

树是项目之间的关系模型,UI 通常使用树结构来表示。例如,浏览器使用树结构来建模 HTML (DOM) 和 CSS (CSSOM)。移动平台还使用树来表示其视图层次结构。

¥Trees are a relationship model between items and UI is often represented using tree structures. For example, browsers use tree structures to model HTML (DOM) and CSS (CSSOM). Mobile platforms also use trees to represent their view hierarchy.

Diagram with three sections arranged horizontally. In the first section, there are three rectangles stacked vertically, with labels 'Component A', 'Component B', and 'Component C'. Transitioning to the next pane is an arrow with the React logo on top labeled 'React'. The middle section contains a tree of components, with the root labeled 'A' and two children labeled 'B' and 'C'. The next section is again transitioned using an arrow with the React logo on top labeled 'React DOM'. The third and final section is a wireframe of a browser, containing a tree of 8 nodes, which has only a subset highlighted (indicating the subtree from the middle section).
Diagram with three sections arranged horizontally. In the first section, there are three rectangles stacked vertically, with labels 'Component A', 'Component B', and 'Component C'. Transitioning to the next pane is an arrow with the React logo on top labeled 'React'. The middle section contains a tree of components, with the root labeled 'A' and two children labeled 'B' and 'C'. The next section is again transitioned using an arrow with the React logo on top labeled 'React DOM'. The third and final section is a wireframe of a browser, containing a tree of 8 nodes, which has only a subset highlighted (indicating the subtree from the middle section).
React 从你的组件创建一个 UI 树。 在此示例中,UI 树随后用于渲染到 DOM。

与浏览器和移动平台一样,React 也使用树结构来管理和建模 React 应用中组件之间的关系。这些树是了解数据如何流经 React 应用以及如何优化渲染和应用大小的有用工具。

¥Like browsers and mobile platforms, React also uses tree structures to manage and model the relationship between components in a React app. These trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size.

渲染树

¥The Render Tree

组件的一个主要特性是能够组合其他组件的组件。在 嵌套组件 中,我们有父组件和子组件的概念,其中每个父组件本身可能是另一个组件的子组件。

¥A major feature of components is the ability to compose components of other components. As we nest components, we have the concept of parent and child components, where each parent component may itself be a child of another component.

当我们渲染 React 应用时,我们可以在树中建模这种关系,称为渲染树。

¥When we render a React app, we can model this relationship in a tree, known as the render tree.

这是一个 React 应用,可以渲染励志名言。

¥Here is a React app that renders inspirational quotes.

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>
    </>
  );
}

Tree graph with five nodes. Each node represents a component. The root of the tree is App, with two arrows extending from it to 'InspirationGenerator' and 'FancyText'. The arrows are labelled with the word 'renders'. 'InspirationGenerator' node also has two arrows pointing to nodes 'FancyText' and 'Copyright'.
Tree graph with five nodes. Each node represents a component. The root of the tree is App, with two arrows extending from it to 'InspirationGenerator' and 'FancyText'. The arrows are labelled with the word 'renders'. 'InspirationGenerator' node also has two arrows pointing to nodes 'FancyText' and 'Copyright'.
React 创建一个“渲染树”,即 UI 树,由渲染的组件组成。

从示例应用中,我们可以构建上面的渲染树。

¥From the example app, we can construct the above render tree.

树由节点组成,每个节点代表一个组件。仅举几例,AppFancyTextCopyright 都是我们树中的节点。

¥The tree is composed of nodes, each of which represents a component. App, FancyText, Copyright, to name a few, are all nodes in our tree.

React 渲染树中的根节点是应用的 根组件。在本例中,根组件是 App,它是 React 渲染的第一个组件。树中的每个箭头都从父组件指向子组件。

¥The root node in a React render tree is the root component of the app. In this case, the root component is App and it is the first component React renders. Each arrow in the tree points from a parent component to a child component.

深入研究

渲染树中的 HTML 标签在哪里?

¥Where are the HTML tags in the render tree?

你会注意到,在上面的渲染树中,没有提及每个组件渲染的 HTML 标签。这是因为渲染树仅由 React 组件 组成。

¥You’ll notice in the above render tree, there is no mention of the HTML tags that each component renders. This is because the render tree is only composed of React components.

React 作为一个 UI 框架,与平台无关。在 React.dev 上,我们展示了渲染到 Web 的示例,它使用 HTML 标记作为其 UI 基础类型。但是 React 应用同样可以渲染到移动或桌面平台,这些平台可能使用不同的 UI 基础类型,例如 UIViewFrameworkElement

¥React, as a UI framework, is platform agnostic. On react.dev, we showcase examples that render to the web, which uses HTML markup as its UI primitives. But a React app could just as likely render to a mobile or desktop platform, which may use different UI primitives like UIView or FrameworkElement.

这些平台 UI 基础类型不是 React 的一部分。无论你的应用渲染到哪个平台,React 渲染树都可以为我们的 React 应用提供洞察力。

¥These platform UI primitives are not a part of React. React render trees can provide insight to our React app regardless of what platform your app renders to.

渲染树代表 React 应用的单个渲染通道。使用 条件渲染,父组件可以根据传递的数据渲染不同的子组件。

¥A render tree represents a single render pass of a React application. With conditional rendering, a parent component may render different children depending on the data passed.

我们可以更新应用以有条件地渲染鼓舞人心的引言或颜色。

¥We can update the app to conditionally render either an inspirational quote or color.

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>
    </>
  );
}

Tree graph with six nodes. The top node of the tree is labelled 'App' with two arrows extending to nodes labelled 'InspirationGenerator' and 'FancyText'. The arrows are solid lines and are labelled with the word 'renders'. 'InspirationGenerator' node also has three arrows. The arrows to nodes 'FancyText' and 'Color' are dashed and labelled with 'renders?'. The last arrow points to the node labelled 'Copyright' and is solid and labelled with 'renders'.
Tree graph with six nodes. The top node of the tree is labelled 'App' with two arrows extending to nodes labelled 'InspirationGenerator' and 'FancyText'. The arrows are solid lines and are labelled with the word 'renders'. 'InspirationGenerator' node also has three arrows. The arrows to nodes 'FancyText' and 'Color' are dashed and labelled with 'renders?'. The last arrow points to the node labelled 'Copyright' and is solid and labelled with 'renders'.
通过条件渲染,在不同的渲染中,渲染树可能会渲染不同的组件。

在此示例中,根据 inspiration.type 是什么,我们可能会渲染 <FancyText><Color>。每个渲染通道的渲染树可能不同。

¥In this example, depending on what inspiration.type is, we may render <FancyText> or <Color>. The render tree may be different for each render pass.

尽管渲染树在渲染过程中可能有所不同,但这些树通常有助于识别 React 应用中的顶层组件和叶组件。顶层组件是距离根组件最近的组件,影响其下所有组件的渲染性能,并且通常包含最复杂的组件。叶子组件靠近树的底部,没有子组件,并且经常被频繁地重新渲染。

¥Although render trees may differ across render passes, these trees are generally helpful for identifying what the top-level and leaf components are in a React app. Top-level components are the components nearest to the root component and affect the rendering performance of all the components beneath them and often contain the most complexity. Leaf components are near the bottom of the tree and have no child components and are often frequently re-rendered.

识别这些组件类别对于了解应用的数据流和性能很有用。

¥Identifying these categories of components are useful for understanding data flow and performance of your app.

模块依赖树

¥The Module Dependency Tree

React 应用中可以使用树建模的另一个关系是应用的模块依赖。当我们将 分解我们的组件 和逻辑放入单独的文件中时,我们创建了 JS 模块,可以在其中导出组件、函数或常量。

¥Another relationship in a React app that can be modeled with a tree are an app’s module dependencies. As we break up our components and logic into separate files, we create JS modules where we may export components, functions, or constants.

模块依赖树中的每个节点都是一个模块,每个分支代表该模块中的一条 import 语句。

¥Each node in a module dependency tree is a module and each branch represents an import statement in that module.

如果我们采用之前的 Inspirations 应用,我们可以构建一个模块依赖树,简称依赖树。

¥If we take the previous Inspirations app, we can build a module dependency tree, or dependency tree for short.

A tree graph with seven nodes. Each node is labelled with a module name. The top level node of the tree is labelled 'App.js'. There are three arrows pointing to the modules 'InspirationGenerator.js', 'FancyText.js' and 'Copyright.js' and the arrows are labelled with 'imports'. From the 'InspirationGenerator.js' node, there are three arrows that extend to three modules: 'FancyText.js', 'Color.js', and 'inspirations.js'. The arrows are labelled with 'imports'.
A tree graph with seven nodes. Each node is labelled with a module name. The top level node of the tree is labelled 'App.js'. There are three arrows pointing to the modules 'InspirationGenerator.js', 'FancyText.js' and 'Copyright.js' and the arrows are labelled with 'imports'. From the 'InspirationGenerator.js' node, there are three arrows that extend to three modules: 'FancyText.js', 'Color.js', and 'inspirations.js'. The arrows are labelled with 'imports'.
Inspirations 应用的模块依赖树。

树的根节点是根模块,也称为入口点文件。它通常是包含根组件的模块。

¥The root node of the tree is the root module, also known as the entrypoint file. It often is the module that contains the root component.

与同一应用的渲染树相比,结构相似,但有一些显着差异:

¥Comparing to the render tree of the same app, there are similar structures but some notable differences:

  • 组成树的节点代表模块,而不是组件。

    ¥The nodes that make-up the tree represent modules, not components.

  • 非组件模块(如 inspirations.js)也在此树中表示。渲染树只封装组件。

    ¥Non-component modules, like inspirations.js, are also represented in this tree. The render tree only encapsulates components.

  • Copyright.js 显示在 App.js 下,但在渲染树中,组件 Copyright 显示为 InspirationGenerator 的子级。这是因为 InspirationGenerator 将 JSX 接受为 子属性,因此它将 Copyright 渲染为子组件,但不导入该模块。

    ¥Copyright.js appears under App.js but in the render tree, Copyright, the component, appears as a child of InspirationGenerator. This is because InspirationGenerator accepts JSX as children props, so it renders Copyright as a child component but does not import the module.

依赖树对于确定运行 React 应用所需的模块很有用。在构建用于生产的 React 应用时,通常有一个构建步骤,它将打包所有必要的 JavaScript 以发送到客户端。负责此操作的工具称为 bundler,打包程序将使用依赖树来确定应包含哪些模块。

¥Dependency trees are useful to determine what modules are necessary to run your React app. When building a React app for production, there is typically a build step that will bundle all the necessary JavaScript to ship to the client. The tool responsible for this is called a bundler, and bundlers will use the dependency tree to determine what modules should be included.

随着应用的增长,打包包的大小通常也会随之增长。对于客户端来说,下载和运行大包的成本很高。较大的包大小可能会延迟 UI 绘制的时间。了解应用的依赖树可能有助于调试这些问题。

¥As your app grows, often the bundle size does too. Large bundle sizes are expensive for a client to download and run. Large bundle sizes can delay the time for your UI to get drawn. Getting a sense of your app’s dependency tree may help with debugging these issues.

回顾

  • 树是表示实体之间关系的常用方法。它们通常用于对 UI 进行建模。

    ¥Trees are a common way to represent the relationship between entities. They are often used to model UI.

  • 渲染树表示单个渲染中 React 组件之间的嵌套关系。

    ¥Render trees represent the nested relationship between React components across a single render.

  • 通过条件渲染,渲染树可能会在不同的渲染中发生变化。使用不同的属性值,组件可能会渲染不同的子组件。

    ¥With conditional rendering, the render tree may change across different renders. With different prop values, components may render different children components.

  • 渲染树有助于识别顶层组件和叶组件。顶层组件会影响其下所有组件的渲染性能,而叶组件通常会频繁重新渲染。识别它们对于理解和调试渲染性能很有用。

    ¥Render trees help identify what the top-level and leaf components are. Top-level components affect the rendering performance of all components beneath them and leaf components are often re-rendered frequently. Identifying them is useful for understanding and debugging rendering performance.

  • 依赖树表示 React 应用中的模块依赖。

    ¥Dependency trees represent the module dependencies in a React app.

  • 构建工具使用依赖树来打包交付应用所需的代码。

    ¥Dependency trees are used by build tools to bundle the necessary code to ship an app.

  • 依赖树对于调试大的打包包非常有用,因为它们会减慢绘制时间并公开优化打包代码的机会。

    ¥Dependency trees are useful for debugging large bundle sizes that slow time to paint and expose opportunities for optimizing what code is bundled.


React 中文网 - 粤ICP备13048890号