如何修复React中useEffect清理函数需取消订阅及异步任务的报错
这个警告触发的核心原因是:streamCourses 的异步回调在组件卸载后才执行,此时调用 setCourseDetails 对已卸载的组件更新状态,就会触发内存泄漏警告。
即使你已经在useEffect返回了unsubscribe函数,仍可能出现该问题:因为回调可能已经进入浏览器的异步任务队列,在unsubscribe执行后才被调度执行。
修复代码
useEffect(() => { // 声明组件挂载状态标记 let isMounted = true; const unsubscribe = streamCourses({ next: (querySnapshot) => { // 仅组件挂载时才更新状态 if (!isMounted) return; const task = querySnapshot.docs.map((docSnapshot) => mapDocTask(docSnapshot) ); setCourseDetails(task); }, error: (error) => { if (!isMounted) return; console.log(error); }, }); // 清理函数:标记组件已卸载+取消订阅 return () => { isMounted = false; unsubscribe(); }; }, [setCourseDetails]);
补充说明
- 这里用
isMounted标记做状态更新的前置判断,就算回调被延迟执行,也不会对已卸载的组件执行状态更新操作。 - 你也可以用
useRef存储挂载标记,效果和直接声明变量一致,对于当前单useEffect场景,直接声明变量写法更简洁。 - 如果修复后仍然出现警告,需要检查
streamCourses返回的unsubscribe方法是否能真正取消订阅,确认该方法的实现是否存在取消失效的问题。
内容的提问来源于stack exchange,提问作者P A T Himaranga
相关产品推荐
相关产品推荐

