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

SWR切换用户账户时先渲染旧缓存数据的问题解决

解决SWR切换用户时显示旧数据的问题

问题根源

SWR 默认以请求 URL 作为缓存唯一标识,切换用户后请求 URL 未变,导致页面会先读取前一个用户的缓存数据,直到新请求完成才更新为当前用户数据,引发数据不一致。

解决方案

1. 给 SWR 缓存键添加用户唯一标识

将用户唯一标识(如用户 ID)加入缓存键,让不同用户的同一接口请求生成独立缓存条目,避免缓存混淆。

修改接口调用代码:

// 从 localStorage 或状态管理中获取当前用户 ID
const userData = JSON.parse(localStorage.getItem('userData') || '{}');
const userId = userData.id;

const {
  data: analyticsData,
  isLoading,
  error,
} = useDataLib<{
  status: number;
  success: any;
}>([`${process.env.NEXT_PUBLIC_API_URL}/dashboard/`, userId]);

更新 useDataLib 函数以支持数组类型的缓存键:

const useDataLib = <T>(swrKey: string | (string | number)[], swrOptions: Record<string, unknown> = {}) => {
  const { data, error, isLoading, mutate } = useSWR<T>(swrKey, fetcher, {
    revalidateOnFocus: false,
    errorRetryCount: 3,
    ...swrOptions,
  });

  return { data, error, isLoading, mutate };
};

2. 退出登录时清空 SWR 全局缓存

在退出登录流程中主动清空所有 SWR 缓存,确保新用户登录后不会读取到任何旧数据。

修改 handleSignOut 函数:

import useSWR, { BareFetcher, mutate } from 'swr';

export const handleSignOut = async () => {
    try {
        const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/${LOGOUT_USER}`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${getToken()}`,
            },
        });

        await response.json();

        Cookies.remove('access');
        Cookies.remove('refresh');
        localStorage.removeItem('userData');

        // 清空所有 SWR 缓存
        mutate(null, undefined, { revalidate: false });

        window.location.href = SIGN_IN;
        return;

    } catch (error) {
        console.error('Failed to logout user', error);
        throw error;
    }
};

3. 确保组件内退出逻辑同步

组件内的退出函数只需保持调用 logOutUser 即可(该函数已包含缓存清空逻辑):

const handleSignOut = async () => {
    await logOutUser();

    localStorage.removeItem("userData");
    setUserData(null);

    dispatch(setAccessToken(null));
    dispatch(setRefreshToken(null));

    router.push(SIGN_IN);
};

原理说明

  • 用户标识加入缓存键:让 SWR 为不同用户的同一接口请求维护独立缓存,从根源避免数据混淆。
  • 全局缓存清空:退出时彻底清除旧用户的缓存数据,确保新用户登录后从空白状态开始请求数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:25:11