fix(auth): очищать кэш React Query при login/logout
Some checks failed
Deploy to Production / Trigger production update (push) Has been cancelled

При входе под другим пользователем в той же вкладке React Query отдавал
закэшированные данные предыдущего пользователя (список инстансов и др.) до
жёсткой перезагрузки, из-за staleTime и отсутствия сброса кэша при смене сессии.

- queryClient вынесен из App.tsx в lib/query-client.ts (доступен вне React)
- auth-store вызывает queryClient.clear() при успешном login и при logout

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
markmorado
2026-07-22 05:22:14 +05:00
parent 42c6acd52e
commit 982522b8b5
3 changed files with 28 additions and 11 deletions

View File

@@ -1,21 +1,12 @@
import { useEffect } from 'react';
import { RouterProvider } from 'react-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { QueryClientProvider } from '@tanstack/react-query';
import { TooltipProvider } from '@/components/ui/tooltip';
import { Toaster } from '@/components/ui/sonner';
import { router } from '@/router';
import { useAuthStore } from '@/stores/auth-store';
import { ConfirmDialogProvider } from '@/components/shared/ConfirmDialog';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 1,
staleTime: 30_000,
refetchOnWindowFocus: false,
},
},
});
import { queryClient } from '@/lib/query-client';
export default function App() {
const loadUser = useAuthStore((s) => s.loadUser);

View File

@@ -0,0 +1,19 @@
import { QueryClient } from '@tanstack/react-query';
/**
* Единый экземпляр QueryClient приложения.
*
* Вынесен из App.tsx в отдельный модуль, чтобы к нему можно было обращаться вне
* React-дерева — в частности, из auth-store для сброса кэша при смене пользователя.
* Без сброса React Query отдавал бы закэшированные данные предыдущего пользователя
* (список инстансов и т.п.) до жёсткой перезагрузки страницы.
*/
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 1,
staleTime: 30_000,
refetchOnWindowFocus: false,
},
},
});

View File

@@ -1,5 +1,6 @@
import { create } from 'zustand';
import { apiClient } from '@/lib/api-client';
import { queryClient } from '@/lib/query-client';
import type { User, LoginRequest, AuthResponse } from '@/types';
interface AuthState {
@@ -34,6 +35,9 @@ export const useAuthStore = create<AuthState>((set) => ({
}
apiClient.setToken(data.access_token);
// Сбрасываем кэш React Query: иначе новый пользователь увидит
// закэшированные данные предыдущего (список инстансов и т.п.).
queryClient.clear();
set({ token: data.access_token, isAuthenticated: true, isLoading: false });
// Load user info
@@ -54,6 +58,9 @@ export const useAuthStore = create<AuthState>((set) => ({
// Ignore logout errors
}
apiClient.setToken(null);
// Полностью очищаем кэш запросов, чтобы данные не утекли следующему
// пользователю, который войдёт в этой же вкладке.
queryClient.clear();
set({ user: null, token: null, isAuthenticated: false });
},