React flushSync()未按预期工作的原因咨询
问题根源
核心问题在于闭包捕获的状态值不会被flushSync修改。
当handleClick开始执行时,函数内部的name变量是从当前组件渲染周期的闭包里捕获的旧值。flushSync的作用是强制React同步更新状态并刷新DOM,但它没办法改变当前正在运行的handleClick函数里已经捕获的name值——这个值在函数执行的那一刻就固定了,所以alert始终拿不到刚输入的最新名字。
可行的解决办法
有两种简单的方式能解决这个问题:
- 直接复用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> ); }
- 用
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
相关产品推荐
相关产品推荐

