React中如何等待setState执行完成后再执行依赖新state的后续操作
问题根源
React的setState系列方法是异步批量更新的,执行setJobTypes(jsonData)后,当前getJobTypes函数闭包中捕获的jobTypes还是初始的空数组,不会立刻同步为最新值,所以你直接在setJobTypes后执行find相当于在空数组上查询,自然返回undefined。
最优解决方案
方案1:直接使用接口返回的原始数据(优先推荐,无额外性能开销)
你刚从接口拿到的jsonData就是最新的岗位类型数据,完全不需要依赖state更新再执行查询,直接替换find的数据源即可:
const [jobTypes, setJobTypes] = useState([]); const getJobTypes = async () => { try { const response = await fetch('/job-types'); const jsonData = await response.json(); setJobTypes(jsonData); // 直接用最新返回的jsonData查询,不需要等state更新 const jobTypeName = jsonData.find(jobType => jobType.ret === jobDetails.jobType) console.log("jobTypeName: ", jobTypeName) } catch (err) { console.error(err.message); } } useEffect(() => { getJobTypes(); }, []);
这个方案没有多余的副作用和重渲染,是性能最好的实现方式。
方案2:新增副作用监听jobTypes变化(适用于逻辑必须依赖state更新后执行的场景)
如果你的后续逻辑必须等jobTypes state更新完成后再触发,可以新增一个单独的useEffect,把jobTypes设为依赖项:
const [jobTypes, setJobTypes] = useState([]); const getJobTypes = async () => { try { const response = await fetch('/job-types'); const jsonData = await response.json(); setJobTypes(jsonData); } catch (err) { console.error(err.message); } } useEffect(() => { getJobTypes(); }, []); // 新增副作用,jobTypes变化后自动执行查询 useEffect(() => { // 可选:加长度判断避免空数组时执行无效查询 if (jobTypes.length === 0) return const jobTypeName = jobTypes.find(jobType => jobType.ret === jobDetails.jobType) console.log("jobTypeName: ", jobTypeName) }, [jobTypes, jobDetails.jobType])
注意要把用到的jobDetails.jobType也加到依赖项里,避免闭包陷阱拿到旧值。
不推荐方案
不要使用flushSync强制同步更新state,会打断React的批量更新逻辑,导致额外的重渲染,性能损耗大,非特殊场景不建议使用。
内容的提问来源于stack exchange,提问作者ArthurJ
相关产品推荐
相关产品推荐

