React中如何正确取消未完成的Ajax请求?
我在用useEffect做数据请求,切换页面时老报“Can’t perform a React state update on an unmounted component”错误。试过AbortController但好像没生效,是不是哪里写错了?
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(res => res.json())
.then(data => setData(data));
return () => controller.abort();
}, []);
fetch 被 abort 时会抛出一个 AbortError,这个错误会打断 .then 链,但如果你不 catch 它,默认行为有点坑。而且更重要的,即使请求被取消了,如果此时组件已经卸载,setData 还是会触发那个 unmounted 错误。
正确写法是这样的:
两个要点:
一是加个 isMounted 标记,在 setData 前判断组件是否还挂着。controller.abort() 只能阻止请求发出去或者拿到响应,但已经拿到响应后还是会往下走 then,所以必须自己判断。
二是 catch 里要区分 AbortError 和其他错误。AbortError 是正常的取消行为,不需要抛出来,其他错误(比如网络断了一般还是得处理一下)。
复制过去试试,基本就解决了。