Ми вивчили API. Тепер поговоримо про те, як не перетворити проект на смітник. TanStack Query дає багато свободи, але "з великою силою приходить велика відповідальність".
Ось правила, які використовують професійні команди.
Ніколи не викликайте useQuery прямо в UI компонентах (якщо це не прототип на коліні).
queryKey або staleTime.useUser().// ❌ Погано: Компонент знає занадто багато
function UserProfile() {
const { data } = useQuery({ queryKey: ['user'], queryFn: fetchUser });
// ...
}
// ✅ Добре: Компонент просто просить дані
function UserProfile() {
const { data } = useUser();
// ...
}
// hooks/useUser.ts
export const useUser = () => {
return useQuery({
queryKey: userKeys.me(),
queryFn: api.getUser,
staleTime: 1000 * 60 * 30, // Ми вирішили, що юзер не змінюється часто
});
};
Ми згадували це в розділі 3, але це варто повторити. Хаос у ключах — головна причина багів інвалідації.
Використовуйте бібліотеку @lukemorales/query-key-factory або пишіть об'єкти вручну.
const todoKeys = {
all: ['todos'] as const,
lists: () => [...todoKeys.all, 'list'] as const,
list: (filters: string) => [...todoKeys.lists(), { filters }] as const,
details: () => [...todoKeys.all, 'detail'] as const,
detail: (id: number) => [...todoKeys.details(), id] as const,
};
Чітко розділяйте відповідальність:
api/todos.ts): Чисті функції, які роблять fetch / axios і повертають Promise. Ніякого React.hooks/useTodos.ts): Кастомні хуки, які використовують API функції та додають логіку кешування (useQuery).components/TodoList.tsx): Використовує хуки та рендерить JSX.Замість того, щоб перевіряти isError у кожному компоненті, використовуйте QueryCache global callbacks для тостів, та Error Boundaries для UI.
// queryClient.ts
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error) => {
toast.error(`Something went wrong: ${error.message}`);
},
}),
});
В компонентах:
// Якщо ви використовуєте useSuspenseQuery, помилка "спливе" до найближчого ErrorBoundary
function App() {
return (
<ErrorBoundary fallback={<div>Something broke!</div>}>
<Suspense fallback={<div>Loading...</div>}>
<UserProfile />
</Suspense>
</ErrorBoundary>
);
}
Не тестуйте TanStack Query. Він протестований авторами. Тестуйте ваші хуки та інтеграцію.
Для тестів створіть окремий queryClient з вимкненими retry (щоб тести не чекали вічність при помилках).
const createTestQueryClient = () => new QueryClient({
defaultOptions: {
queries: {
retry: false, // Важливо для тестів!
},
},
});
test('renders todos', async () => {
render(
<QueryClientProvider client={createTestQueryClient()}>
<TodoList />
</QueryClientProvider>
);
// ...
});
TanStack Query — це потужний інструмент, який при правильному використанні робить ваш код чистішим, а додаток — швидшим.
Чек-лист професіонала:
staleTime налаштовано глобально та перевизначено локально де треба.DevTools.Вітаємо! Ви пройшли курс майстерності TanStack Query. Тепер йдіть і видаліть весь цей useEffect код зі своїх проектів! 🚀
Просунуті Патерни та Оптимізація
Ви вже вмієте робити базові речі. Тепер перейдемо до технік "чорного поясу". Ці патерни допоможуть вирішити складні архітектурні завдання та оптимізувати продуктивність.
Server-Side Rendering (SSR) та Гідратація
Якщо ви використовуєте Next.js, Remix або Astro, ви хочете, щоб ваші дані завантажувалися на сервері для SEO та швидкого першого відтворення (LCP).