Skip to content

渲染和提交

🔄 React渲染的三个步骤

React将组件显示到屏幕上的过程可以比喻为餐厅服务流程:

  1. 触发渲染 📣 - 类似服务员接收订单
  2. 渲染组件 👨‍🍳 - 类似厨师准备食物
  3. 提交到DOM 🍽️ - 类似服务员将食物送到桌上

📣 步骤1:触发渲染

有两种情况会触发渲染:

🔰 初次渲染

  • 应用启动时通过createRoot创建根节点
  • 调用root.render(<App />)将组件放入DOM容器
jsx
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

🔄 状态更新重新渲染

  • 组件通过setState函数更新状态
  • 状态更新会自动将渲染请求加入队列

👨‍🍳 步骤2:React渲染组件

触发渲染后,React会调用组件确定要显示的内容:

  • 初次渲染:React调用根组件
  • 重新渲染:React调用触发更新的函数组件

渲染过程是递归的

  1. 如果组件返回其他组件,React会继续渲染那些组件
  2. 这个过程持续直到React知道所有要显示的内容

⚠️ 渲染的重要特性

渲染必须是纯计算

  • 相同输入,相同输出:给定相同的props和state,组件应始终返回相同的JSX
  • 不修改已有对象:不应更改渲染前存在的对象或变量
  • 无副作用:不应在渲染期间发送请求、设置超时、修改DOM等

💡 在严格模式下,React会调用每个组件的函数两次,帮助发现不纯函数导致的问题

🍽️ 步骤3:React提交更改到DOM

完成组件渲染后,React会修改DOM:

  • 初次渲染:使用appendChild()DOM API将所有创建的DOM节点放到屏幕上
  • 重新渲染:仅应用必要的最小操作,使DOM与最新渲染输出匹配

React只会更新实际发生变化的DOM部分!如果渲染结果与上次相同,React不会修改DOM。

🎨 浏览器绘制

DOM更新后,浏览器会重新绘制屏幕。这个过程称为"浏览器绘制"(browser painting)。

💡 性能优化提示

  • React默认会渲染更新组件及其所有嵌套组件
  • 如果性能出现问题,可以使用以下技术优化:
    • memo():跳过不必要的重渲染
    • useMemo():缓存计算结果
    • useCallback():缓存函数定义

⚠️ 不要过早优化!先理解渲染流程,在真正需要时再进行优化

📝 总结

  • 🔄 React渲染过程包括三个步骤:触发、渲染和提交
  • 🔰 初次渲染通过createRootroot.render()触发
  • 🔄 状态更新会触发重新渲染
  • ⚛️ React递归渲染组件直到没有更多嵌套组件
  • 🧪 使用严格模式可以发现渲染中的不纯操作
  • 🎯 React只更新必要的DOM部分,这是其高效性能的关键

参考:React官方文档-渲染和提交