axios发送get请求后调用React useState hooks状态未更新问题求助
排查建议
- 先排查React状态更新的异步特性问题
你写的const test = match属于组件首次渲染的同步执行代码,而axios.get是异步请求,setMatch执行时当前渲染周期已经结束,本次渲染闭包里的match永远是初始的null。状态更新后会触发组件重新渲染,只有下次渲染时才能拿到更新后的match值。
你可以添加以下代码验证状态是否正常更新:
如果控制台先后打印useEffect(() => { console.log('match状态更新,当前值:', match) }, [match])null和你拿到的res.data数组,说明状态更新是正常的,只是你在错误的时机取值导致看到的一直是null。 - 检查组件重渲染是否被阻断
如果添加上述useEffect后只打印了一次null,说明setMatch没有触发组件重渲染,优先排查以下情况:- 组件是否被
React.memo包裹,且自定义的比较函数错误返回了true跳过了更新 - 类组件场景下是否写了错误的
shouldComponentUpdate逻辑 - 是否有上层组件错误拦截了渲染流程
- 组件是否被
- 排查状态引用是否未变化导致更新被跳过
React的状态更新默认做浅比较,如果res.data和之前match的引用是同一个(比如你提前把旧的match赋值给了某个变量,修改后又传回去),React会认为状态没有变化跳过更新。你可以尝试修改代码传入新的数组引用验证:setMatch([...res.data]) - 排查是否有其他逻辑覆盖了状态值
检查是否有多个并发异步操作都在修改match状态,比如后续发起的请求返回了null把你当前的赋值结果覆盖了,或者全局作用域的status变量被其他逻辑修改后又触发了赋值。 - 排查断点调试的逻辑问题
你在setMatch行打断点时,setMatch还未执行完成,当前作用域下的match仍然是本次渲染的旧值,哪怕setMatch执行完毕,本次闭包内的变量也不会被修改,新值只能在下一次渲染的作用域中获取。
内容的提问来源于stack exchange,提问作者Paolo Di Pietro
相关产品推荐
相关产品推荐

