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

React组件设相同状态值,前两次点击触发重渲染?原因解析

问题分析与解答

为什么两次点击按钮都会打印「Parent Rerendered!」?

React函数组件的默认行为是:只要调用setState方法,无论新状态值和当前值是否相同,都会触发组件重渲染。

在你的代码中:

  • 第一次点击按钮时,stateVar从初始的undefined变为1,状态发生变化,组件正常重渲染,顶层的console.log执行。
  • 第二次点击按钮时,你依然调用setStateVar(1),此时新值和当前stateVar的1完全一致,但React并不会自动跳过这次重渲染流程,组件会重新执行一遍,所以console.log再次打印。

为什么放入useEffect后仅第一次点击打印?

你提到的这个现象,应该是因为实际使用的useEffect指定了依赖数组[stateVar](可能代码示例中漏写了)。当useEffect的依赖数组包含stateVar时:

  • 第一次点击后,stateVar从undefined变为1,依赖项发生变化,useEffect的回调函数执行,打印日志。
  • 第二次点击时,stateVar的值没有改变,依赖项未更新,useEffect不会触发回调,因此不再打印。

如果你的useEffect没有设置依赖数组(如你贴出的代码),理论上每次组件重渲染都会执行回调,第二次点击也会打印。这种情况可能是测试时的误差,或者存在未提及的代码逻辑。

如何实现「仅状态变化时才重渲染」?

如果想让组件在状态值未变化时跳过重渲染,可以通过两种方式优化:

  1. 函数式更新判断值是否变化
    修改按钮的点击逻辑,在setState的函数式更新中判断值是否相同,相同则返回旧值:
<button
  onClick={() => {
    setStateVar(prev => {
      if (prev === 1) return prev; // 值未变化时返回旧值,避免触发重渲染
      return 1;
    })
  }}
>
  Rerender UI
</button>
  1. 用React.memo包裹组件
    React.memo会对组件的props进行浅比较,若props未变化则跳过重渲染(对于无props的组件,状态值不变时也会跳过):
import React, { useState } from 'react';

const UseCallbackComp = React.memo(() => {
  const [stateVar, setStateVar] = useState<any>()
  console.log("Parent Rerendered!")
  return (
    <>
      <div>UseCallbackComp content</div>
      <div>
        <button
          onClick={() => {
            setStateVar(1)
          }}
        >
          Rerender UI
        </button>
      </div>
    </>
  )
})

export default UseCallbackComp;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:29