React使用useState存储Firestore数据时首次渲染state未更新问题
问题根本原因
你遇到的是React状态更新的异步特性和useEffect执行顺序的问题,核心有两点:
- React的
setState(包括useState返回的更新方法)本身是异步批量执行的,调用setModule之后,当前闭包里的module变量不会立刻拿到最新值,要等到下一次组件重渲染才会更新。 - 你把
console.log(module)写在了useEffect的同步执行流里,而getModuleInfo是异步函数:你调用getModuleInfo()之后,不会等它内部的await逻辑执行完,就会立刻执行后面的console.log,此时接口请求还没返回,setModule还没被调用,拿到的自然是初始的空数组。
热更新时能拿到正确值的原因
你修改代码触发React热更新的时候,组件会保留当前已有的state值,然后重新执行useEffect,这时候module已经是之前接口返回赋值后的值了,所以打印出来是正确的,这只是热更新的特殊表现,不是正常的首次加载逻辑。
修复方案
方案1:在setModule之后直接打印接口返回值
// 修改getModuleInfo内部逻辑 else { let ModuleInfov2 = ModuleInfo.data(); setModule(ModuleInfov2) console.log(ModuleInfov2) // 直接打印接口返回的最新值即可 }
方案2:单独监听module的变化执行对应操作
如果你需要拿到更新后的state值做其他逻辑处理,可以单独写一个useEffect监听module的变化:
useEffect(() => { console.log(module) // 每次module更新时都会执行,首次接口返回赋值后也会触发 }, [module])
内容的提问来源于stack exchange,提问作者Sander van Maastricht
相关产品推荐
相关产品推荐

