梗概
useEffect 回调本身不能是 async;需要在内部启动异步,并在清理函数中取消未完成任务,避免“卸载后仍 setState”的内存泄漏。
两种常用取消方案
支持异步的useEffect
1. 闭包标记法(isMounted/isCancelled)
useEffect(() => {
let cancelled = false;
(async () => {
const res = await fetch(url).then(r => r.json());
if (!cancelled) setData(res);
})();
return () => { cancelled = true; };
}, [url]);
2. AbortController(推荐给 fetch/XHR)
useEffect(() => {
const controller = new AbortController();
(async () => {
try {
const res = await fetch(url, { signal: controller.signal }).then(r => r.json());
setData(res);
} catch (e) {
if ((e as any).name !== 'AbortError') throw e;
}
})();
return () => controller.abort();
}, [url]);
相关