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

React函数组件调用setState为何触发两次重渲染?

问题复现代码
export const Component = () => {
    const [count, setCount] = useState<number>(0);

    const renderCount = useRef<number>(0);
    renderCount.current =  renderCount.current + 1;

    return (<>
        <div>{`Rendered ${renderCount.current} times`}</div>
        <button type="button" onClick={() => setCount(count + 1)}>{`Clicked ${renderCount.current} times`}</button>
    </>);
}

预期行为:点击按钮仅触发1次重渲染,count状态更新后完成UI重建即可
实际表现:每次点击按钮触发状态变更后,组件都会执行两次重渲染,渲染计数每次累加2

两次渲染的产生原因

这个是React 18+版本开发环境的正常设计,不是代码bug,核心触发原因是项目默认开启了严格模式(Strict Mode):

  • 严格模式下React会在开发阶段主动重复执行组件渲染流程、重复走一遍挂载/卸载生命周期,目的是提前捕获代码里的不规范写法:比如渲染阶段产生的副作用污染、useEffect未编写清理逻辑等问题。这类重复渲染行为仅在开发环境存在,生产环境打包构建后不会触发。
  • 你把renderCount.current自增的逻辑直接写在了组件函数体的渲染执行阶段,没有做任何隔离,严格模式下每次状态更新触发的渲染流程都会被React执行2次,所以计数每次会累加2,看起来就像是触发了两次重渲染。
  • 如果要验证逻辑,可以临时移除项目入口文件里根组件外层的<StrictMode>包裹,此时点击按钮就只会触发1次渲染,但不推荐日常开发中关闭严格模式,它能帮你提前规避很多隐蔽的代码问题。
  • 额外提一句示例代码本身的逻辑问题:按钮上的点击次数展示写法是错误的,点击次数应该绑定count这个状态值,而不是记录渲染次数的ref。ref值变化本身不会触发视图更新,这里只是刚好ref值和渲染流程同步才显示出数字,业务逻辑上不应该这么写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:54:22