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

为何useEffect在组件重新渲染前执行?React计数器问题求助

React计数器alert弹窗与DOM更新顺序问题解决

问题根源

React状态更新后,会先完成DOM的渲染更新,再执行useEffect钩子。但alert是同步阻塞的API,一旦执行就会暂停浏览器所有后续任务(包括DOM渲染),所以即便useEffect在渲染后触发,alert弹出时DOM还没来得及更新,直到你关闭弹窗,浏览器才会继续完成h1的数值更新。

另外你代码里的prev变量是普通let声明,每次组件重新渲染都会被重置为0,完全起不到保存前值的作用,还错误地加到了useEffect的依赖数组里,属于冗余代码。

修复代码

把alert放到setTimeout中,让它进入宏任务队列,等当前渲染周期结束、DOM更新完成后再执行:

import { useEffect, useState } from "react";

export default function App() {
  const [number, setNumber] = useState(0);

  useEffect(() => {
    if (number !== 0) {
      setTimeout(() => {
        alert("Number changed to " + number);
      }, 0);
    }
  }, [number]);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => setNumber(n => n + 5)}>
        +5
      </button>
    </>
  );
}

关键说明

  • setTimeout(fn, 0)不会真的等0秒,而是把回调推迟到当前所有同步任务(包括React的DOM更新)完成后再执行,这样就能保证h1的数值先更新,再弹出alert。
  • 移除了无用的prev变量,避免不必要的useEffect触发和代码混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:10:31