在你的组件显示在屏幕上之前,它们必须先被 React 渲染。了解这个过程中的步骤将帮助你思考代码是如何执行的,并解释其行为。
🌐 Before your components are displayed on screen, they must be rendered by React. Understanding the steps in this process will help you think about how your code executes and explain its behavior.
你将学习到
- React 中的渲染意味着什么
- React 何时以及为何渲染组件
- 在屏幕上显示组件所涉及的步骤
- 为什么渲染并不总是产生 DOM 更新
想象你的组件就像厨房里的厨师,从各种食材中组装出美味的菜肴。在这种情况下,React 就是服务员,接收顾客的点单并将他们的餐点送达。这个请求和呈现用户界面的过程有三个步骤:
🌐 Imagine that your components are cooks in the kitchen, assembling tasty dishes from ingredients. In this scenario, React is the waiter who puts in requests from customers and brings them their orders. This process of requesting and serving UI has three steps:
- 触发 渲染(将客人的订单送到厨房)
- 渲染组件(在厨房准备订单)
- 提交到 DOM(将订单放在表格上)

Trigger 
Render 
Commit
Illustrated by Rachel Lee Nabors
步骤 1:触发渲染
🌐 Step 1: Trigger a render
组件渲染的原因有两个:
🌐 There are two reasons for a component to render:
- 这是组件的初始渲染。
- 组件(或其某个祖级)的状态已被更新。
初始渲染
🌐 Initial render
当你的应用启动时,你需要触发初始渲染。框架和沙箱有时会隐藏这段代码,但它是通过调用 createRoot 并传入目标 DOM 节点来完成的,然后调用它的 render 方法并传入你的组件:
🌐 When your app starts, you need to trigger the initial render. Frameworks and sandboxes sometimes hide this code, but it’s done by calling createRoot with the target DOM node, and then calling its render method with your component:
import Image from './Image.js'; import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')) root.render(<Image />);
试着注释掉 root.render() 调用,看看组件会消失!
🌐 Try commenting out the root.render() call and see the component disappear!
状态更新时重新渲染
🌐 Re-renders when state updates
一旦组件被初次渲染,你可以通过使用 set 函数 更新其状态来触发进一步的渲染。更新组件的状态会自动排队进行渲染。(你可以把这些想象成餐厅的客人在首次点餐后,根据他们的口渴或饥饿状态继续点茶、甜点以及各种东西。)
🌐 Once the component has been initially rendered, you can trigger further renders by updating its state with the set function. Updating your component’s state automatically queues a render. (You can imagine these as a restaurant guest ordering tea, dessert, and all sorts of things after putting in their first order, depending on the state of their thirst or hunger.)

State update... 
...triggers... 
...render!
Illustrated by Rachel Lee Nabors
步骤 2:React 渲染你的组件
🌐 Step 2: React renders your components
在你触发渲染之后,React 会调用你的组件来确定在屏幕上显示什么。“渲染”就是 React 调用你的组件。
🌐 After you trigger a render, React calls your components to figure out what to display on screen. “Rendering” is React calling your components.
- 在初始渲染时, React 将调用根组件。
- **对于后续的渲染,**React 将会调用触发渲染的状态更新的函数组件。
这个过程是递归的:如果更新后的组件返回了其他组件,React 将接着渲染_那个_组件,如果那个组件也返回了某些内容,它将接着渲染_那个_组件,依此类推。该过程将继续,直到没有更多嵌套组件,并且 React 完全知道屏幕上应该显示的内容。
🌐 This process is recursive: if the updated component returns some other component, React will render that component next, and if that component also returns something, it will render that component next, and so on. The process will continue until there are no more nested components and React knows exactly what should be displayed on screen.
在以下示例中,React 将多次调用 Gallery() 和 Image():
🌐 In the following example, React will call Gallery() and Image() several times:
export default function Gallery() { return ( <section> <h1>Inspiring Sculptures</h1> <Image /> <Image /> <Image /> </section> ); } function Image() { return ( <img src="https://i.imgur.com/ZF6s192.jpg" alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals" /> ); }
- **在初始渲染期间,**React 将为
<section>、<h1>和三个<img>标签创建 DOM 节点。 - **在重新渲染期间,**React 会计算它们的哪些属性(如果有的话)自上次渲染以来发生了变化。在下一步提交阶段之前,它不会使用这些信息做任何事情。
深入研究
🌐 Optimizing performance
如果更新的组件在组件树中位置很高,那么渲染更新组件内所有嵌套组件的默认行为对性能并不理想。如果遇到性能问题,可以在 Performance 部分找到几种可选择的解决方法。不要过早优化!
🌐 The default behavior of rendering all components nested within the updated component is not optimal for performance if the updated component is very high in the tree. If you run into a performance issue, there are several opt-in ways to solve it described in the Performance section. Don’t optimize prematurely!
步骤 3:React 提交更改到 DOM
🌐 Step 3: React commits changes to the DOM
在渲染(调用)你的组件后,React 将修改 DOM。
🌐 After rendering (calling) your components, React will modify the DOM.
- 对于初始渲染, React 将使用
appendChild()DOM API 将它创建的所有 DOM 节点显示在屏幕上。 - 对于重新渲染, React 将应用最小必要的操作(在渲染时计算!)以使 DOM 与最新的渲染输出匹配。
只有在渲染之间存在差异时,React 才会改变 DOM 节点。 例如,这里有一个组件,每秒都会根据父组件传递的不同 props 重新渲染。注意你可以在 <input> 中添加一些文本,更新它的 value,但当组件重新渲染时,文本并不会消失:
export default function Clock({ time }) { return ( <> <h1>{time}</h1> <input /> </> ); }
这是可行的,因为在最后这一步中,React 只会用新的 time 更新 <h1> 的内容。它看到 <input> 出现在 JSX 中的位置与上次相同,所以 React 不会触碰 <input> —— 或它的 value!
🌐 This works because during this last step, React only updates the content of <h1> with the new time. It sees that the <input> appears in the JSX in the same place as last time, so React doesn’t touch the <input>—or its value!
尾声:浏览器绘画
🌐 Epilogue: Browser paint
在渲染完成并且 React 更新了 DOM 之后,浏览器将重新绘制屏幕。虽然这个过程被称为“浏览器渲染”,但为了在文档中避免混淆,我们将其称为“绘制”。
🌐 After rendering is done and React updated the DOM, the browser will repaint the screen. Although this process is known as “browser rendering”, we’ll refer to it as “painting” to avoid confusion throughout the docs.

Illustrated by Rachel Lee Nabors