React UI 渲染树

Posted on 2026-04-03 17:21  打杂滴  阅读(2)  评论(0)    收藏  举报

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

当渲染 React 应用程序时,可以在一个称为渲染树的树中建模这种关系。

 

quotes.js 如下(名言/引文):
// eslint-disable-next-line import/no-anonymous-default-export
export default [
  "Don’t let yesterday take up too much of today.” — Will Rogers",
  "Ambition is putting a ladder against the sky.",
  "A joy that's shared is a joy made double."
  ];
 
FancyText.js 如下:
export default function FancyText({title, text}) {
  return title
    ? <h1>{text}</h1>
    : <h5>{text}</h5>
}
 
Copyright.js 如下:
export default function Copyright({year}) {
  return <p>©️ {year}</p>;
}
 
InspirationGenerator.js 如下:
import * as React from 'react';
import quotes from './quotes';
import FancyText from './FancyText';

export default function InspirationGenerator({children}) {
  const [index, setIndex] = React.useState(0);
  const quote = quotes[index];
  const next = () => setIndex((index + 1) % quotes.length);

  return (
    <>
      <p>Your inspirational quote is:</p>
      <FancyText text={quote} />
      <button onClick={next}>Inspire me again</button>
      {children}
    </>
  );
}
 

逐行解析
‌导入模块‌:

import * as React from 'react';:导入 React 库,以便使用 React 的功能。
import quotes from './quotes';:从本地文件 ./quotes 导入一个名为 quotes 的数组,其中包含多个励志语录。
import FancyText from './FancyText';:导入自定义组件 FancyText,用于展示语录文本。
‌函数组件定义‌:

export default function InspirationGenerator({children}):定义一个名为 InspirationGenerator 的函数组件,并接收 children 作为 props。children 表示组件内部的子元素。
‌状态管理‌:

const [index, setIndex] = React.useState(0);:使用 useState 钩子创建一个状态变量 index,初始值为 0。这个变量用于跟踪当前显示的语录在 quotes 数组中的索引位置。
‌获取当前语录‌:

const quote = quotes[index];:根据当前的 index 值从 quotes 数组中获取对应的语录。
‌切换语录的函数‌:

const next = () => setIndex((index + 1) % quotes.length);:定义一个函数 next,用于切换到下一个语录。它通过将当前 index 加 1 后对数组长度取模来实现循环切换。例如,当 index 为数组最后一个元素的索引时,下一个 index 会回到 0。
‌渲染部分‌:

<p>Your inspirational quote is:</p>:显示提示语录的标题。
<FancyText text={quote} />:使用自定义组件 FancyText 来展示当前的语录。text 属性传入当前的 quote。
<button onClick={next}>Inspire me again</button>:渲染一个按钮,点击时会调用 next 函数,切换到下一个语录。
{children}:将传入的子元素渲染在组件内部,允许外部传入额外的内容。
组件功能总结
‌语录展示‌:组件会显示当前索引对应的语录。
‌语录切换‌:点击按钮可以切换到下一个语录,当到达数组末尾时会自动回到开头。
‌可扩展性‌:通过 children 属性,可以向组件内部添加额外的内容。

useState
useState 是一个 React Hook,它允许你向组件添加一个 状态变量。

const [state, setState] = useState(initialState)
参考
useState(initialState)
set 函数,例如 setSomething(nextState)
用法
为组件添加状态
根据先前的 state 更新 state
更新状态中的对象和数组
避免重复创建初始状态
使用 key 重置状态
存储前一次渲染的信息

 

为组件添加状态
在组件的顶层调用 useState 来声明一个或多个 状态变量。

import { useState } from 'react';

function MyComponent() {
const [age, setAge] = useState(42);
const [name, setName] = useState('Taylor');
// ...
按照惯例使用 数组解构 来命名状态变量,例如 [something, setSomething]。

useState 返回一个只包含两个项的数组:

该状态变量 当前的 state,最初设置为你提供的 初始化 state。
set 函数,它允许你在响应交互时将 state 更改为任何其他值。

 
 
App.js 如下:
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <div>
      <FancyText title  text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2026} />
      </InspirationGenerator>
    </div>
  );
}

image

image

 

渲染树表示 React 应用程序的单个渲染过程。在 条件渲染 中,父组件可以根据传递的数据渲染不同的子组件。

我们可以更新应用程序以有条件地渲染励志语录或颜色。

Copyright.js:

export default function Copyright({year}) {
  return <p>©️ {year}</p>;
}
 
Color.js:
export default function Color({value}) {
  return <div  className="colorbox" style={{backgroundColor: value, width:80,height:80}} />
}

 

inspirations.js:

// eslint-disable-next-line import/no-anonymous-default-export
export default [
  {type: 'quote', value: "Don’t let yesterday take up too much of today.” — Will Rogers"},
  {type: 'color', value: "#B73636"},
  {type: 'quote', value: "Ambition is putting a ladder against the sky."},
  {type: 'color', value: "#256266"},
  {type: 'quote', value: "A joy that's shared is a joy made double."},
  {type: 'color', value: "#F9F2B4"}
];
 
InspirationGenerator.js: 
import * as React from 'react';
import inspirations from './inspirations';
import FancyText from './FancyText';
import Color from './Color';

export default function InspirationGenerator({children}) {
  const [index, setIndex] = React.useState(0);
  const inspiration = inspirations[index];
  const next = () => setIndex((index + 1) % inspirations.length);

  return (
    <>
      <button onClick={next}>Inspire me again</button>
      <p>Your inspirational {inspiration.type} is:</p>
      {inspiration.type === 'quote'
      ? <FancyText text={inspiration.value} />
      : <Color value={inspiration.value} />}
      {children}
    </>
  );
}
 
FancyText.js:
 
export default function FancyText({title, text}) {
  return title
    ? <h1>{text}</h1>
    : <h5>{text}</h5>
}
 
App.js:
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <div>
      <FancyText title  text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2026} />
      </InspirationGenerator>
    </div>
  );
}

image

 

image

 

 

image

 

 在React的组件树语境里,‌renders‌表示“渲染”或“渲染出”,用来体现组件之间的渲染依赖关系:

图里的App组件renders了InspirationGenerator和FancyText,意思是App负责将这两个子组件渲染到页面中,是父子组件的渲染调用关系。
InspirationGenerator``renders了Color和Copyright,说明它会调用这两个组件的渲染逻辑,把它们的内容展示出来。
虚线的renders?则代表条件渲染:InspirationGenerator会根据特定条件,决定是否渲染FancyText,不同渲染流程里,最终呈现的组件可能不一样。
简单来说,renders就是React里组件“生成UI内容”的动作,通过它能清晰梳理出组件的嵌套与渲染逻辑。

 

 https://zh-hans.react.dev/learn/understanding-your-ui-as-a-tree

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3