React 组件为什么会重复渲染
一句话结论#
React 组件默认:父组件渲染 → 所有子组件自动跟着渲染! 不管子组件的 props 变没变,都会重新渲染。
这就是 99% 的重复渲染来源。
一、组件重复渲染的 4 大核心原因#
1. 父组件渲染,子组件默认无条件重渲染(最常见)#
React 没有自动给子组件做优化,父一更新,子全更。
function Parent() {
const [a] = useState(0)
return <Child /> // 父渲染 → 子一定渲染
}jsx2. 自身 state 变化#
只要执行 setState,组件一定重渲染。
即使值没变,也会渲染:
setCount(1)
setCount(1) // 依然会触发渲染jsx3. props 引用变化(对象/数组/函数)#
因为 React 用 === 比较
<Child list={[1,2,3]} /> // 每次都是新数组 → 子组件渲染
<Child fn={() => {}} /> // 每次都是新函数 → 子组件渲染jsx4. context value 变化#
只要 context.Provider 的 value 变了
所有用到这个 context 的后代组件全部重渲染
二、最关键知识点:#
React 组件渲染 ≠ DOM 更新#
- 组件渲染 = 运行函数 / 生成 VDOM
- DOM 更新 = 真实改变页面
组件重复渲染 ≠ 页面卡 但渲染太多 = 浪费性能 = 页面卡
三、如何判断组件在重复渲染?#
加一句 console.log 就行:
function Child() {
console.log("子组件渲染了") // 打印多了就是重复渲染
return <div></div>
}jsx四、如何解决重复渲染?(最实用)#
1. 子组件包 React.memo()#
让子组件只有 props 真正变化时才渲染
const Child = React.memo(function Child() { ... })jsx2. 用 useMemo 缓存对象/数组#
const list = useMemo(() => [1,2,3], [])jsx3. 用 useCallback 缓存函数#
const fn = useCallback(() => { ... }, [])jsx4. 拆分组件#
把会变的 state 和不变的 UI 拆分开。
总结#
React 组件重复渲染主要有 4 个原因:
- 父组件渲染,子组件默认无条件重渲染(最主要)
- 自身 state 被更新
- props 是引用类型(对象/数组/函数),每次都创建新引用
- 使用的 context value 发生变化
优化方式:
React.memo、useMemo、useCallback、组件拆分。
父渲染 → 子默认渲染 引用变化 → 子一定渲染 自身 setState → 自身一定渲染