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
相关产品推荐
相关产品推荐

