React.useState状态同步问题:如何使A、B、C处token值一致?
问题原因
React的useState状态更新是异步批量执行的,调用setToken后,当前函数作用域内的token变量并不会立刻更新,还是保留着更新前的旧值。所以:
- A处的
console.log和B处传给commitMutation的都是旧token - 当组件重新渲染后,C处的
TestToaster会拿到更新后的新token,导致三者值不一致
解决方案
方案1:提前生成新token并复用
先创建新的token变量,再把它传给setToken,同时在A、B处直接使用这个新变量,确保三处用的是同一个值:
const calculate = () => { const newToken = `name:${uuid()}`; // 先生成新token setToken(newToken); // 更新状态 console.log('in calculate: '+ newToken); // A处用newToken commitMutation({ variables: { input: { token: newToken, // B处用newToken }, } }); };
这样A、B用的是刚生成的新token,C在组件重新渲染后也会拿到这个新token,三者就一致了。
方案2:用useEffect监听token变化
如果需要在token更新后再执行日志或mutation,可以把这部分逻辑放到useEffect里,依赖token:
const calculate = () => { setToken(() => `name:${uuid()}`); }; useEffect(() => { if (token) { // 避免初始空值触发 console.log('in useEffect: '+ token); // 对应原A处 commitMutation({ variables: { input: { token, // 对应原B处 }, } }); } }, [token]); // 当token变化时执行
这种方式下,只有当token真正更新(组件重新渲染)后,才会执行日志和mutation,此时A(移到useEffect里)、B、C用的都是新token,也能保证一致。
内容的提问来源于stack exchange,提问作者Hayden
相关产品推荐
相关产品推荐

