You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel SWR切换路由时数据不更新的正确解决方法

问题根因

这个问题的核心出在SWR的key设计上:

  • 你传给useSWR的第一个参数(请求key)是写死的固定值api/scores,完全没有跟随路由变化。SWR的缓存匹配、请求触发全靠这个key做唯一标识,只要key不变,不管路由怎么切,SWR都会直接返回该key对应的缓存值,哪怕手动调用mutate,请求的还是原来的接口地址,自然拿不到对应分类的比分数据。
  • next/link触发的是客户端路由跳转,不会整页刷新,也不会重新挂载复用的Scores组件,所以写死的请求地址不会更新。你之前监听router.asPath调用mutate不生效,本质就是触发重验证时,用的还是旧key对应的旧接口,根本没请求当前路由匹配的比分接口。
  • 用window.location跳转能正常更新,是因为这种方式会触发整页刷新,整个React应用重新初始化,相当于首次加载页面,自然能拿到对应路径下的初始数据。
正确实现方式

不需要手动监听路由写mutate,只要把SWR的key和当前路由动态绑定即可,SWR检测到key变化时会自动发起新请求、更新数据,同时不同路由的缓存会自动隔离,切回已访问路由时还能直接读缓存实现秒开。

以Next.js App Router为例,代码调整如下:

'use client'
import { usePathname } from 'next/navigation'
import useSWR from 'swr'
import axios from 'axios'
// 省略ScoreComponent、fallbackData的引入

export function Scores() {
    const pathname = usePathname()
    // 根据当前路由动态生成请求key,不同路由对应不同key
    const requestUrl = pathname === '/scores'
        ? '/api/scores'
        : `/api/scores/${pathname.split('/').pop()}` // 自动拼接/soccer、/basketball后缀

    const fetcher = async (url: string) => {
        const res = await axios.get(url)
        return res.data
    }

    const { data } = useSWR(requestUrl, fetcher, {
        fallbackData,
        revalidateOnFocus: true,
        revalidateOnReconnect: true,
        refreshInterval: 300000,
        shouldRetryOnError: false,
        revalidateOnMount: true,
    })

    if (!data) return <div>比分加载中...</div>

    return (
        <div>
            {data.map((score) => (
                // 记得给列表项加唯一key,避免React渲染异常
                <ScoreComponent key={score.matchId} score={score} />
            ))}
        </div>
    )
}

如果用的是Pages Router,把usePathname换成useRouter()返回的pathname字段即可,核心逻辑完全一致。

额外注意项
  • 删掉之前写的监听router.asPath调用mutate的useEffect逻辑,多余的触发会导致重复请求。
  • 接口路径建议统一加上前导斜杠,写成/api/scores而非api/scores,避免嵌套路由场景下相对路径拼接错误。
  • 如果需要在切路由时立刻展示加载态,可以从useSWR返回值里解构isValidating字段做自定义加载提示。

内容的提问来源于stack exchange,提问作者Jason McFarlane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:42:17