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

React设置相同state时父重渲染子不渲染的原因?

React setState传入相同值时的重渲染差异:父组件执行但子组件不渲染?

问题描述

我在研究React中state setter的重渲染时机时遇到了一个困惑的现象:

  • 初始state为9,点击「setNumber to 9」按钮,无任何组件重渲染,符合预期(React用Object.is()判断state相同则跳过)。
  • 首次点击「setNumber to 10」按钮,App和Num组件都打印重渲染日志,符合预期。
  • 但再次点击「setNumber to 10」按钮时,App组件触发了重渲染(打印日志),Num组件却没有。我尝试用memo包裹Num组件,结果依旧如此,这是什么原因?

代码示例

App组件

import { useState } from "react";
import "./App.css";
import Num from "./Components/Num";

function App() {
  const [number, setNumber] = useState(9);

  console.log("Component 'App' just re-render.");

  return (
    <div>
      <h1>If we setNumber to same value, will react do re-render?</h1>
      <Num number={number} />
      <button className="firstBtn" onClick={() => setNumber(9)}>
        setNumber to 9
      </button>
      <button className="btn" onClick={() => setNumber(10)}>
        setNumber to 10
      </button>
    </div>
  );
}

export default App;

Num组件

const Num = ({ number }) => {
  console.log("Component 'num' just re-render.");

  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      <h3 style={{ marginRight: "8px", color: "#ff5fa2" }}>Number:</h3>
      <h3>{number}</h3>
    </div>
  );
};

export default Num;

原因解析

这是React在不同组件层级的重渲染优化逻辑差异导致的:

1. 父组件(App)的重渲染逻辑

调用setState时,即便新值与当前state完全相同,React不会直接跳过父组件的函数执行。它会先运行App组件的函数体(因此会打印日志),生成新的虚拟DOM,之后对比新旧虚拟DOM,确认没有需要更新的真实DOM内容后,才会跳过DOM更新。简言之:组件函数执行了,但真实DOM没变动。

2. 子组件(Num)的不重渲染逻辑

  • 未用memo包裹时:这是React的自动 bailout 优化在起作用——当子组件的props是原始类型(比如这里的数字number)且新旧值完全一致时,React会自动跳过子组件的重渲染流程。
  • 用memo包裹后:这个优化变成了显式行为——React会对传入的props做Object.is()浅对比,发现number没有变化,直接跳过Num的函数执行与渲染,因此不会打印日志。

额外验证方法

如果想让Num在父组件重渲染时也跟着渲染,可以给Num加一个动态变化的props,比如:

<Num number={number} key={Math.random()} />

此时每次App重渲染时key都会变化,React会认为是新的组件实例,Num就会触发重渲染。

内容的提问来源于stack exchange,提问作者cardsfan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:23:10