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

为何在组件主体中调用setState会引发无限渲染循环?

为什么在组件主体中设置相同状态值会触发无限渲染循环?

核心原因:渲染阶段调用setState的特殊行为

你之前的认知没错——React确实会通过Object.is比较新旧状态值,相同则不会触发重渲染,但这个逻辑的生效场景是在渲染完成后触发的状态更新(比如事件回调、useEffect中)。而如果是在**组件渲染过程中(组件主体代码执行阶段)**调用setState,规则完全不同:

  1. 渲染中调用setState会直接中断当前渲染,调度新渲染
    当组件正在执行主体代码(比如你的示例里的setCount(1))时调用状态更新,React不会等到当前渲染完成再做值比较,而是会立即丢弃当前的渲染流程,直接调度一个新的渲染周期。

  2. 无限循环的形成逻辑
    在你的第一个示例中:

    • 第一次渲染时,执行setCount(1),React中断当前渲染,启动新渲染
    • 新渲染启动后,组件主体代码再次执行setCount(1),再次中断当前渲染,调度下一次渲染
    • 这个过程无限重复,因为每次渲染都没机会完成,也就不会触发React的“新旧值比较”逻辑来终止循环

关于你第二个示例的现象解释

你观察到只打印Rendering...,没有Didmount和Unmount,原因是:
组件的挂载流程(useEffect的回调触发)只有在渲染完全完成后才会执行。而你的代码每次渲染都被setCount(1)中断,组件从未完成挂载,所以useEffect不会触发,卸载回调自然也不会执行。每次都是渲染到一半被打断重启,因此只会重复输出Rendering...。

正确的做法

永远不要在组件的渲染阶段(组件主体代码、useMemo/useCallback的依赖计算等同步执行的渲染逻辑中)直接调用状态更新方法。状态更新应该放到:

  • 事件处理器(比如按钮点击回调)
  • useEffect钩子(针对副作用场景)
  • 其他异步回调(比如API请求完成后)

内容的提问来源于stack exchange,提问作者이주희

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:40:08