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

React flushSync()未按预期工作的原因咨询

问题根源

核心问题在于闭包捕获的状态值不会被flushSync修改。

当handleClick开始执行时,函数内部的name变量是从当前组件渲染周期的闭包里捕获的旧值。flushSync的作用是强制React同步更新状态并刷新DOM,但它没办法改变当前正在运行的handleClick函数里已经捕获的name值——这个值在函数执行的那一刻就固定了,所以alert始终拿不到刚输入的最新名字。

可行的解决办法

有两种简单的方式能解决这个问题:

  1. 直接复用prompt的结果,不依赖状态
    既然已经能直接获取到prompt的输入值,没必要绕状态去拿,直接把结果存到变量里用就行:
export default function FeedbackForm() {
  const [name, setName] = useState('');

  function handleClick() {
    const newName = prompt('What is your name?');
    flushSync(() => {
      setName(newName);
    });
    alert(`Hello, ${newName}!`);
  }

  return (
    <button onClick={handleClick}>
      Greet
    </button>
  );
}
  1. 用useRef存储最新状态值
    useRef的.current属性是可变的,不受闭包限制,能始终拿到最新的状态:
export default function FeedbackForm() {
  const [name, setName] = useState('');
  const nameRef = useRef('');

  useEffect(() => {
    nameRef.current = name;
  }, [name]);

  function handleClick() {
    flushSync(() => {
      setName(prompt('What is your name?'));
    });
    alert(`Hello, ${nameRef.current}!`);
  }

  return (
    <button onClick={handleClick}>
      Greet
    </button>
  );
}

第一种方法更简洁,推荐优先用这种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:19:57