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

React useEffect实现计数器:两段代码差异及第一段失效原因咨询

React useEffect计数器代码差异及第一段失效原因分析

第一段代码为何无法正常工作

先看第一段代码:

function IntervalHookCounter() {
  const [count,setCount] = useState(0)

  useEffect(()=>{
      const interval = setInterval(tick,1000)
  },[])

  const tick = ()=>{
      setCount(count+1)
  }
}

问题出在闭包和状态更新方式的组合上:

  • useEffect的依赖是[],说明这个effect只会在组件首次挂载时执行一次,创建的定时器会一直引用挂载时的tick函数。
  • 挂载时tick里的count是闭包捕获的初始值0,之后不管组件状态怎么更新,这个闭包里的count永远是0。所以每次定时器触发tick,执行的都是setCount(0+1),count会被设置为1,但后续再触发时,还是用0来计算,结果还是1,界面就停在1不再变化了。

两段代码的核心差异

第二段代码:

function IntervalHookCounter() {
  const [count,setCount] = useState(0)

  useEffect(()=>{
      const interval = setInterval(tick,1000)
  },[])

  const tick = ()=>{
      setCount(prevState=>prevState+1)
  }
}

两段的唯一区别是setCount的调用方式:

  • 第一段用的是直接基于当前变量值更新:setCount(count+1),依赖的是闭包中的count值,一旦闭包捕获的是旧值,更新就会出错。
  • 第二段用的是函数式更新:setCount(prevState=>prevState+1),这种方式下,React会自动把当前最新的状态值作为参数传给回调函数,不管闭包里的count是什么旧值,都能拿到最新的状态来计算下一个值,所以定时器每次触发都能正确让count加1,计数器正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:42:23