SWR预加载数据后为什么组件还是会闪一下加载状态?

司徒俊俊 阅读 74

我在用SWR做数据预加载,明明在进入页面前就调用了fetcher,但组件首次渲染时还是会短暂显示loading状态,体验很不好。是我预加载的方式不对吗?

我是在路由跳转前这样预加载的:

import { mutate } from 'swr'

// 跳转前预加载
mutate('/api/user', fetchUser())

// 页面组件里
const { data, isValidating } = useSWR('/api/user', fetchUser)
if (isValidating && !data) return <div>Loading...</div>

按理说mutate已经把数据塞进缓存了,为什么useSWR第一次还是拿不到data,非要等一轮revalidate?

我来解答 赞 11 收藏
二维码
手机扫码查看
1 条解答
令狐晓英
这个问题挺常见的,本质上是因为SWR的默认行为——即使缓存里已经有数据,它也会在组件挂载时立即发起一次revalidate来确保数据是最新的。

所以你mutate进去的数据确实在缓存里,但useSWR一挂载就触发了revalidate,isValidating瞬间变true,你的loading条件 isValidating && !data 就成立了,loading状态就这么闪了一下。

解决办法很简单,给useSWR加个配置项关掉首次挂载的自动revalidate:

const { data, isValidating } = useSWR('/api/user', fetchUser, {
revalidateOnMount: false
})
``

加上这个选项后,SWR首次挂载时就不会发起请求了,直接用你mutate进去的缓存数据,loading就不会闪了。

如果你还需要在某些情况下手动触发重新获取,可以用
mutate('/api/user')` 再调一次。

希望能帮到你!
点赞
2026-03-18 08:04