SWR在组件卸载后还会触发setState吗?

司马若惜 阅读 78

我用SWR请求数据,但在组件卸载后好像还报了警告,说不能在已卸载的组件上setState。是不是SWR没处理好取消逻辑?

我试过在useEffect里加了取消标志,但感觉SWR应该自己处理了才对。代码大概是这样:

const { data, error } = useSWR('/api/user', fetcher);
if (error) return <div>failed</div>;
if (!data) return <div>loading...</div>;
return <div>{data.name}</div>;
我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
程序猿志利
SWR确实会自动处理组件卸载时的请求取消,但这个警告可能来自其他原因。常见的情况是:

1. SWR会在组件卸载后自动取消请求,但如果你在fetcher里手动调用了setState就会有问题
2. 或者你在组件里用了其他副作用操作没清理

一般这样处理最稳妥:

const { data, error } = useSWR('/api/user', fetcher, {
revalidateOnFocus: false, // 减少不必要的重请求
dedupingInterval: 2000 // 设置去重时间
});

useEffect(() => {
return () => {
// 手动清理其他可能的状态操作
};
}, []);


如果问题还在,检查下你的fetcher函数里有没有直接操作组件状态的代码。SWR本身不会在卸载后setState,但如果你在fetcher里写了类似这样的代码就会有问题:

const fetcher = async () => {
const res = await fetch('/api/user');
setSomeState(...) // 这里就有问题
return res.json();
}


另外可以升级到最新版SWR,他们在这方面处理得越来越好了。
点赞
2026-03-06 10:13
轩辕瑄旗
SWR 内部已经处理了组件卸载后的清理逻辑,你不需要自己在 useEffect 里加取消标志,那是多此一举。SWR 会在组件卸载时忽略掉未完成的请求结果,不会触发 setState。

你贴的这段代码本身是没问题的。如果还在报错,大概率是你的 fetcher 函数里做了什么骚操作,或者你在 if 条件里调用了 useSWR(这是大忌,Hook 必须在顶层调用)。

确保你的 fetcher 是个纯净的 Promise 返回函数,就像下面这样:

const fetcher = url => fetch(url).then(res => res.json());

function Profile() {
const { data, error } = useSWR('/api/user', fetcher);

if (error) return
failed to load
;
if (!data) return
loading...
;
return
hello {data.name}
;
}


只要保证 fetcher 逻辑简单,SWR 就能搞定剩下的。如果是 SWR 2.0 版本,它还会自动 abort 掉请求,连网都不费了。
点赞 1
2026-03-04 12:24