You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免React父组件状态更新时子组件的不必要重渲染?

如何避免React父组件状态更新时子组件的不必要重渲染?

嘿,看起来你已经尝试用memo来优化子组件渲染了,但还是遇到了父组件更新时子组件跟着跑的问题,我来帮你理清楚问题出在哪,以及怎么解决~

问题原因拆解

先给你捋清楚当前两个子组件的情况:

  • 对于Child2:你没有用memo包裹它,而React的默认逻辑是父组件重渲染时,所有子组件都会跟着重渲染,不管有没有传递props,所以每次点击counter按钮,Child2必然会打印child 2 rerenders。
  • 对于ChildComponent:你已经用memo包裹了,但如果还是看到它打印child renders,大概率是开发环境下React Strict Mode导致的双渲染——React 18的Strict Mode在开发阶段会让组件额外渲染一次,用来帮你提前发现副作用相关的bug,这不是真正的“不必要重渲染”,生产环境打包后这个行为会自动消失。

具体解决方案

1. 给Child2添加memo包裹

要阻止Child2的不必要重渲染,只需要像ChildComponent一样用memo包裹它就行:

// Child2.js
import { memo } from "react";

const Child2 = () => {
  console.log("child 2 rerenders");
  return <div>HIii theere</div>;
};

export default memo(Child2);

这样当App因counter更新而重渲染时,Child2因为没有props变化,会被memo跳过重渲染。

2. 排查ChildComponent的“异常重渲染”

如果你在开发环境中每次点击counter都看到child renders,先检查你的项目入口文件(比如main.jsx/index.jsx)里,App是不是被StrictMode包裹了:

// 示例入口文件
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

const root = createRoot(document.getElementById('root'));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

Strict Mode在开发环境下会触发组件两次渲染,这是正常的调试行为,目的是帮你检测组件里的副作用问题。如果暂时不想看到这个效果,你可以先注释掉<StrictMode>标签,这时候再点击counter,你会发现ChildComponent不会再打印child renders了——因为memo已经生效,阻止了它的不必要重渲染。

3. 未来扩展:子组件带props时的优化

如果以后你的子组件需要接收props,要注意避免传递不稳定的引用类型(比如内联函数、内联对象),因为每次父组件重渲染都会创建新的引用,导致memo的浅比较认为props变化了,子组件还是会重渲染。

这时候可以用useCallback包裹函数,useMemo包裹对象,确保引用稳定:

// 父组件App里的例子
const handleChildClick = useCallback(() => {
  // 你的点击逻辑
}, []); // 依赖数组为空,确保函数引用始终稳定

// 传递给子组件
<ChildComponent onClick={handleChildClick} />

这样就能彻底杜绝子组件的不必要重渲染啦~

备注:内容来源于stack exchange,提问作者Suyash Srivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:49:48