React中多个setTimeout回调需等最后一个超时后才执行的问题
问题原因与解决方案
你的问题核心出在使用数组索引作为Toast组件的key上。
当你用key={i}时,数组元素的增减会导致后续组件的key发生移位:比如先添加toastA(key=0),1秒后添加toastB(key=1);3秒后toastA的定时器触发,removeToast将其从数组中移除,此时数组只剩toastB,React会把原来key=1的toastB组件,替换成key=0的组件(因为数组索引变了)。这会导致toastB的组件重新渲染,useEffect依赖的toast对象发生变化,旧的定时器被清除,同时重新设置一个新的3秒定时器——相当于toastB的计时被重置了。
以此类推,每移除一个toast,后面所有toast的组件都会被复用、重新渲染,定时器全部被重置,最终所有回调都会等到最后一个toast的超时时间一起执行。
解决方法
把组件的key从数组索引换成toast的唯一id,确保每个Toast组件有稳定且唯一的标识:
<div className="toastsContainer"> {toasts.map((toast) => ( <Toast key={toast.id} toast={toast} removeToast={removeToast} /> ))} </div>
注意:要保证每个toast对象在创建时都带有唯一的id(可以用自增数字、UUID等方式生成),这样React就能准确识别每个组件,不会在数组变化时错误地复用组件。
这样修改后,每个Toast组件的定时器会独立运行,到时间后只会移除对应的toast,其他组件不受影响,不会出现定时器被重置的问题。
内容的提问来源于stack exchange,提问作者Liam Welsh
相关产品推荐
相关产品推荐

