SWR在React组件卸载时如何取消未完成的请求?

♫熙妍 阅读 57

我在用SWR获取用户数据时,发现组件卸载后还在发起请求,控制台报错说”Can’t cancel mutate…”。我试过在useEffect的清理函数里调用mutate.cancel,但好像没生效。

代码大概是这样写的:


import useSWR from 'swr'

function UserPage({ userId }) {
  const { data, mutate } = useSWR(`user/${userId}`, fetchUser)

  useEffect(() => {
    return () => mutate.cancel() // 这里应该有问题?
  }, [mutate])

  return 
{data?.name}
}

如果把mutate取消的逻辑改成在fetch函数里返回abortController,会不会更可靠?或者SWR有内置的取消机制没用对?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
Des.胜楠
SWR 会自动取消未完成的请求,但需要确保组件卸载时不再触发 mutate。

你用 mutate.cancel() 的方式不对,应该用 useEffect 返回的函数来取消未完成的请求,但要在 useSWR 的配置里设置 revalidateOnMount: false

改法如下:

function UserPage({ userId }) {
const { data } = useSWR(user/${userId}, fetchUser, { revalidateOnMount: false })

useEffect(() => {
return () => {
// 这里 SWR 会自动取消未完成的请求
}
}, [])

return <div>{data?.name}</div>
}


SWR 内部已经处理了 AbortController,不需要自己返回。你手动调用 mutate.cancel() 是多余的。
点赞 4
2026-02-04 08:07
程序员统思
SWR内置了取消机制,组件卸载时会自动取消未完成的请求,不需要手动调mutate.cancel。你看到的错误可能是因为mutate用法不对。改成这样就行了:

useEffect(() => {
return () => mutate.current?.abort()
}, [mutate])


如果还是不行,确保SWR版本是最新,老版本确实有些bug。
点赞 7
2026-01-29 20:04