RTK Query и альтернативы
Серверное состояние в Redux, теги и сравнение с TanStack Query, SWR, Apollo, RSC.
Обновлено
Что такое RTK Query
RTK Query — часть Redux Toolkit, которая занимается серверным состоянием: получает данные из API, хранит их в кэше, дедуплицирует запросы, управляет загрузкой/ошибками и автоматически обновляет данные после мутаций. Это аналог TanStack Query, но построенный поверх Redux.
Идея: вы больше не пишете useEffect + fetch + useState для загрузки + редьюсер для данных. Вы один раз описываете эндпоинты, а RTK Query генерирует хуки.
Полный API
// shared/api/base-api.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
tagTypes: ['Post'],
endpoints: build => ({
getPosts: build.query<Post[], { page: number }>({
query: ({ page }) => `posts?page=${page}`,
providesTags: result => [
...(result ?? []).map(p => ({ type: 'Post' as const, id: p.id })),
{ type: 'Post', id: 'LIST' },
],
}),
addPost: build.mutation<Post, NewPost>({
query: body => ({ url: 'posts', method: 'POST', body }),
invalidatesTags: [{ type: 'Post', id: 'LIST' }],
}),
}),
})
export const { useGetPostsQuery, useAddPostMutation } = api'use client'
const { data, isLoading, error } = useGetPostsQuery({ page })
const [addPost, { isLoading: saving }] = useAddPostMutation()Теги — как он понимает, что обновить
| Понятие | Роль |
|---|---|
tagTypes |
категории данных: 'Post', 'User' |
providesTags |
запрос объявляет, какие данные он содержит: { type: 'Post', id: 1 } |
invalidatesTags |
мутация объявляет, какие данные она изменила |
| итог | запросы с инвалидированными тегами перезапрашиваются автоматически |
{ type: 'Post' } без id инвалидирует все посты; { type: 'Post', id: 1 } — только пост 1. Тот же принцип, что у cacheTag / updateTag в Next и queryKey / invalidateQueries в TanStack Query.
Альтернативы — сравнение
| RTK Query | TanStack Query | SWR | Apollo / urql | Server Components | |
|---|---|---|---|---|---|
| Для | REST / чего угодно | REST / чего угодно | REST / чего угодно | GraphQL | чего угодно, на сервере |
| Зависит от | Redux | ничего | ничего | GraphQL | Next / RSC |
| Кэш определяется | эндпоинтом + аргументами, тегами | queryKey |
ключом (URL) | типом + id (нормализованно) | 'use cache' + cacheTag |
| Инвалидация | теги, декларативно | invalidateQueries |
mutate(key) |
автоматически по типу/id | updateTag / revalidateTag |
| Размер | большой (с Redux) | средний | маленький | большой | 0 КБ на клиенте |
| Когда | Redux уже есть | по умолчанию на клиенте | простые задачи, в стиле Vercel | GraphQL API | по умолчанию в Next для вывода |
Практическая рекомендация:
- В Next.js App Router начинайте с Server Components для выводимых данных и Server Actions для мутаций.
- Нужны живые данные на клиенте (polling, бесконечная прокрутка, дашборд) → TanStack Query.
- В проекте уже есть Redux → RTK Query, чтобы не было двух систем.
- GraphQL API → Apollo или urql.
Частые ошибки
- Копировать результат запроса в слайс Redux или в
useState— два источника истины. - Нет тегов → после мутации список не обновляется.
- Один
createApiна приложение; эндпоинты добавляют черезinjectEndpointsиз каждой фичи.
Коротко
- RTK Query = серверное состояние поверх Redux; эндпоинты → сгенерированные хуки.
providesTags+invalidatesTags= автоматическое обновление после мутаций.- Альтернативы: TanStack Query (по умолчанию на клиенте), SWR (просто), Apollo (GraphQL), Server Components (Next).