React中异步循环更新useState仅生效一次的原因排查
问题原因与解决办法
这是因为React useState的闭包特性导致的:当你在forEach循环里发起异步操作时,所有then回调函数捕获的都是当前组件渲染周期里found的快照值——也就是初始的0。
举个例子,假设values有3个元素,三个异步回调里的found都是0,每次调用setFound(found + 1)其实都是执行setFound(0 + 1),最终状态只会被设置成1。后面的两次更新相当于重复设置同一个值,React会忽略这类重复的状态更新,所以页面最终只显示1。
解决办法
把状态更新改成函数式更新的形式,给setFound传递一个函数,这个函数会接收上一次的状态值作为参数,返回新的状态值。这样每次更新都会基于最新的状态,而非闭包里的旧快照。
修改后的递增函数:
const incrementFound = () => { setFound(prevFound => prevFound + 1); }
或者直接在异步回调中写:
values.forEach((item) => { doSomething([item]).then(() => { console.log("Removed " + item); setFound(prev => prev + 1); }); });
这样不管有多少个异步回调执行,每次都会在上一次的状态基础上加1,最终状态值会正确累加。
内容的提问来源于stack exchange,提问作者Baiqing
相关产品推荐
相关产品推荐

