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

React的setState Hook未变更状态时为何触发两次组件渲染?

React 17 相同状态值触发多余渲染原因

这是React 17版本的固有特性,和Strict Mode没有关系,核心差异来自useState的更新 bailout 逻辑:

  1. 首次页面加载时,会触发一次默认渲染,控制台输出:
    Rendering app
    Rendering man with Blue Shirt
    
  2. 第一次点击「Change to red shirt」按钮时,状态从Blue Shirt更新为Red Shirt,属于有效状态变更,触发第二次渲染,控制台输出对应渲染日志。
  3. 后续两次点击按钮时,传入的新状态和当前shirt的值完全相等,React 17 会执行一次预防性渲染校验:
    • 会完整运行一次组件函数体,所以你会看到console.log语句执行
    • 后续diff阶段对比前后渲染结果没有变化,就不会提交更新到DOM,也不会触发useEffect等生命周期回调
    • 这次校验执行后,后续再传入相同的状态值,不会再重复执行组件函数

React 18已经优化了这个场景:当setState传入和当前完全相等的状态值时,不会再执行组件函数体,也就不会出现多余的日志输出。

你可以通过添加useEffect验证真实更新时机:

useEffect(() => {
  console.log("Shirt 状态真的发生了变更:", shirt)
}, [shirt])

你会发现这个useEffect只会在状态首次加载、第一次点击红按钮时执行,多余的预防性渲染不会触发它。


内容的提问来源于stack exchange,提问作者Nícolas Amarante

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:48:03