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

为何React状态未变更,点击按钮后组件仍二次渲染并打印日志?

案例一:相同状态值触发组件二次渲染的原因

点击按钮第二次时,App组件似乎会进行二次渲染,但按道理状态设置为相同值时不应变更,为何会出现这种情况?

import React, { useState } from "react";

const App = () => {
  const [someState, changeSomeState] = useState(null);
  console.log(someState);
  console.log('App component rendered');

  return (
    <>
      <button
        onClick={() => {
          changeSomeState(6666);
        }}
      >
        Button in App
      </button>
    </>
  );
};

export default App;

原因

  • 这是React开发模式下Strict Mode(严格模式)的特性:严格模式会重复执行一次渲染逻辑,用来检测代码中的非幂等操作、潜在副作用等问题,帮你提前发现bug。
  • 生产模式下,这种额外渲染会被移除,此时第二次点击按钮,因为状态值和当前值完全相同,React会直接跳过组件重渲染。
  • 如果你在项目的根组件外层包裹了<React.StrictMode>,去掉它就能在开发模式下看到正常的渲染次数。

案例二:父组件二次渲染但子组件仅渲染一次的原因

点击按钮后,App组件出现二次渲染,但嵌套在App内的Test组件仅渲染一次,这是为什么?

Test组件代码(每次重渲染都会执行console.log):

import React from "react";

const Test = () => {
  console.log("Test component rendered");

  return <div>Test</div>;
};

export default Test;

App组件代码:

import React, { useState } from "react";
import Test from "./Test";
const App = () => {
  const [someState, changeSomeState] = useState(null);
  console.log(someState);

  return (
    <>
      <Test />
      <button
        onClick={() => {
          changeSomeState(6666);
        }}
      >
        Button in App
      </button>
    </>
  );
};

export default App;

原因

  • React默认会做浅比较优化:当父组件重渲染时,React会检查子组件的props是否发生变化。如果子组件没有接收任何props,或者props和上一次完全一致,React会判定子组件的输出不会改变,直接复用之前的渲染结果,不会再次执行子组件的函数体。
  • 这里的Test组件既没有接收props,也没有依赖父组件的任何状态或上下文,所以React直接跳过了它的重渲染。
  • 要是想让Test组件跟着父组件重渲染,可以给它传递一个动态变化的props(比如<Test value={someState} />),或者给它设置一个随状态变化的key(<Test key={someState} />),这时父组件重渲染时Test也会跟着重新执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:32:02