React异步函数中并发两个请求时setState状态未更新问题
问题根源
这个现象和Promise.all并发请求没有任何关系,本质是React状态更新机制+JS闭包特性导致的正常表现,你的接口请求、状态更新本身都是成功的,只是打印状态的时机和位置错了。
核心原理
- 函数组件每一次渲染都会生成独立的闭包,当前渲染周期内所有代码拿到的
first、second状态值,都是这次渲染时固定的值,不会被同步修改。你在首次渲染时触发的getData函数,闭包里捕获的first永远是初始值null。 - React的状态更新是异步批处理的:调用
setFirst、setSecond不会立刻修改当前作用域内的状态变量,只会调度一次组件重渲染,等重渲染完成后,新的渲染周期闭包里的first才会是你传入的data1值。 - 你打印的
data1是接口返回后存在当前函数作用域的局部变量,和React状态无关,所以能正常输出预期的数组结果。 - 你之前单请求场景没遇到这个问题,只是因为没有在setState之后立刻在同一个函数里打印状态值,实际上单请求场景下这么写log结果是完全一样的。
验证状态是否更新成功
加一个监听first变化的effect,就能在状态真正更新后拿到正确值:
useEffect(() => { console.log('更新后的first值:', first); }, [first]);
这个effect会在first变化、组件完成重渲染后执行,打印出来的就是你存入的接口数据。
开发注意事项
- 如果
setFirst、setSecond之后的逻辑需要用到接口返回的数据,直接使用已经拿到的局部变量data1、data2即可,不需要等状态更新。 - 永远不要在调用setState的同一个同步/异步执行上下文里,立刻读取对应的状态变量,你拿到的永远是当前闭包里的旧值。
内容的提问来源于stack exchange,提问作者R. Anderson
相关产品推荐
相关产品推荐

