SWR在组件卸载后还会触发setState吗?
我用SWR请求用户数据,但切换页面时偶尔报“Can’t perform a React state update on an unmounted component”错误,是不是SWR没处理好取消逻辑?
我试过在useEffect里加isMounted判断,但感觉不太对。代码大概是这样:
import useSWR from 'swr';
function UserProfile({ userId }) {
const { data, error } = useSWR(<code>/api/user/${userId}</code>, fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return <div>Hello, {data.name}</div>;
}
fetch而没配AbortController。SWR 默认会通过 key 变化自动取消旧请求,但前提是你的 fetcher 支持中止——它不会主动去 abort 一个不支持 abort 的请求。所以当组件卸载时,如果请求还在进行中,而 fetcher 又没处理取消逻辑,等响应回来就会触发 setState,导致报错。
推荐的做法是:写一个支持
AbortController的 fetcher,或者用 SWR 官方推荐的swr+fetch的组合方式,比如:或者更简单点,直接用 SWR 官方文档里推荐的写法:用
useSWR的fetcher直接接fetch,SWR 会自动注入signal:注意这里 key 要支持为 null,避免无效请求;另外如果你用的是自定义 fetcher,务必确保它能正确处理
signal(SWR 会把signal作为最后一个参数传进去)。最后你试的
isMounted确实不是好办法——既违反 React 18 的并发原则,也掩盖了真正的问题。直接让请求可中止才是正解。