← [ BACK_TO_NOTES ]

React组件渲染与重渲染

React 组件什么时候渲染、为什么重渲染,以及如何正确理解重渲染与性能问题的关系。

#frame #react #concept #growing

[!info] related notes

React组件渲染与重渲染

理解 React,不能只停留在“状态变了页面就变了”,还要理解组件什么时候会重新执行,以及这和性能问题到底是什么关系。

一句话定义

React 组件重渲染,本质上是组件函数重新执行,得到新的 UI 描述,再由 React 比较差异并更新必要部分。

常见触发来源

  • 组件自己的 state 变化
  • 父组件重渲染并传入新的 props
  • context 值变化

每次重渲染时到底发生了什么

  1. 组件函数重新执行
  2. Hook 按顺序重新调用
  3. React 从对应槽位取出旧状态
  4. 得到新的 JSX 结果
  5. React 比较前后差异
  6. 只提交必要的 DOM 更新
  7. 需要时再运行 effect cleanup 和新的 effect

这也是为什么 React 组件里的普通变量不会“自动记住上一次值”。

为什么 Hooks 总和重渲染绑在一起

因为每次渲染都会形成一套新的变量绑定和新的闭包。

function Demo() {
  const [count, setCount] = useState(0)

  function handleClick() {
    console.log(count)
  }

  return <button onClick={handleClick}>{count}</button>
}

这里的 handleClick 拿到的是“这次渲染里的 count”,不是某个永恒不变的变量。

所以一旦你把回调交给定时器、订阅、异步流程,就很容易遇到闭包旧值问题。

一个很重要的事实

重渲染不等于性能问题。

真正可能昂贵的是:

  • 大量子树无意义重复计算
  • 大列表渲染
  • 昂贵计算重复执行
  • effect 和副作用反复运行

为什么很多人会误解它

因为“组件函数重新执行”听起来像很重,但 React 的模型本来就是声明式重算,问题通常出在状态设计和更新边界,而不是重渲染这个词本身。

和优化 Hook 的关系

  • useMemo 主要优化计算结果复用
  • useCallback 主要优化函数引用稳定
  • useRef 用于保存不该触发重渲染的值

常见误解

  • 以为函数组件只会创建一次
  • 以为“函数重新执行”就等于 DOM 整体重建
  • 以为只要 rerender 就一定要上 memo
  • 以为所有性能问题都来自 rerender 次数

真正更值得先查的是:

  • 状态是不是放错位置了
  • 是否建了不该有的派生状态
  • 是否写了不必要的 Effect
  • 是否有昂贵计算或长列表

最短记忆方式

先接受“重渲染是正常现象”,再去定位真正昂贵的是哪一段工作。

学习检查

不看正文回答:

  1. React 组件 rerender 与真实 DOM 更新为什么不是同一个事件?
  2. state、parent render、context 分别怎样触发或传导 render?
  3. 为什么函数组件每次 render 都会形成新的局部变量和闭包快照?
  4. “组件重新执行”为什么不等于“整个 DOM 重建”?
  5. 为什么 rerender 本身通常不是需要消灭的问题?
  6. memo、useMemo、useCallback 应该建立在哪些性能证据之上?
  7. 给一个页面卡顿案例,先判断 render 次数、单次 render 成本、DOM commit、Effect、长列表中哪一项才是真瓶颈。
创建于 2026/3/19 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本