Хук useQuery в Redux Toolkit RTK Query представляет
собой основной инструмент для декларативного выполнения запросов к
серверу и получения состояния этих запросов в компоненте. Его поведение
полностью управляется входными параметрами и набором опций, которые
определяют жизненный цикл запроса, кэширование, повторные запросы,
выборку данных и стратегию обновления.
useQueryТипичная форма использования:
const { data, error, isLoading, isFetching } = useGetUsersQuery(arg, options)
Где:
arg — аргумент запроса (параметры запроса)options — объект конфигурации поведения запросаПервый параметр хука — это входные данные для endpoint’а.
useGetUserQuery(1)
useGetPostsQuery('latest')
Используется, когда endpoint ожидает один параметр.
useGetPostsQuery({
page: 1,
limit: 20,
sort: 'desc'
})
Объектный аргумент позволяет:
Некоторые endpoint’ы не требуют параметров:
useGetSettingsQuery()
skipОдна из ключевых опций управления выполнением запроса.
Полностью отключает выполнение запроса.
const { data } = useGetUserQuery(id, {
skip: !id
})
true — запрос не выполняетсяfalse — запрос выполняется как обычноskipToken
как альтернативный способ пропускаВместо skip можно использовать специальный токен:
import { skipToken } from '@reduxjs/toolkit/query'
const { data } = useGetUserQuery(id ?? skipToken)
Особенности:
optionspollingIntervalОпределяет частоту автоматического обновления данных.
useGetNotificationsQuery(null, {
pollingInterval: 5000
})
refetchOnMountOrArgChangeКонтролирует повторный запрос при монтировании компонента.
useGetUserQuery(id, {
refetchOnMountOrArgChange: true
})
false — используется кэш без повторного запросаtrue — всегда выполняется новый запросrefetchOnFocusАвтоматический повтор запроса при возврате фокуса на вкладку браузера.
useGetUserQuery(id, {
refetchOnFocus: true
})
RTK Query отслеживает событие visibilitychange и при
возвращении фокуса:
refetchOnReconnectЗапуск повторного запроса при восстановлении интернет-соединения.
useGetUserQuery(id, {
refetchOnReconnect: true
})
online событие браузераselectFromResultОдна из наиболее мощных и недооценённых опций.
Позволяет выбирать и преобразовывать часть результата запроса.
const { userName } = useGetUserQuery(id, {
selectFromResult: ({ data }) => ({
userName: data?.name
})
})
useGetPostsQuery(undefined, {
selectFromResult: ({ data }) => ({
posts: data?.filter(post => post.published)
})
})
RTK Query подписывает компонент только на выбранные поля, а не на весь результат запроса.
transformResponse
(на уровне endpoint, но влияет на хук)Хотя не является параметром хука, часто используется совместно.
getUser: builder.query({
query: (id) => `user/${id}`,
transformResponse: (response) => response.data
})
keepUnusedDataForКонтролирует время хранения данных в кэше после отписки.
useGetUserQuery(id, {
keepUnusedDataFor: 60
})
subscribe и модель
подписокКаждый вызов useQuery создаёт подписку на данные в
store.
keepUnusedDataFor)refetch как метод
управленияХук возвращает функцию refetch:
const { refetch } = useGetUserQuery(id)
refetch()
isFetching vs
isLoadingПараметры состояния запроса имеют различную семантику.
isLoadingisFetchingconst { isLoading, isFetching } = useGetUserQuery(id)
error и обработка
ошибокconst { error } = useGetUserQuery(id)
baseQueryРеальные сценарии часто используют несколько параметров одновременно.
useGetUserQuery(id, {
skip: !id,
pollingInterval: 10000,
refetchOnFocus: true,
refetchOnReconnect: true,
selectFromResult: ({ data, isFetching }) => ({
user: data,
loading: isFetching
})
})
Каждый параметр влияет на кэш-ключ:
arg формирует уникальный cache keyskip исключает участие в кэшированииrefetch обновляет существующий entryRTK Query строит жизненный цикл запроса на основе конфигурации:
argkeepUnusedDataForОпции напрямую влияют на количество обновлений компонента:
selectFromResult минимизирует ререндерыpollingInterval увеличивает частоту обновленийisFetching вызывает дополнительные обновления UIskip полностью исключает рендер запросной логикиАргумент запроса сравнивается по строгому равенству:
useGetPostsQuery({ page: 1 }) // каждый рендер = новый запрос
Решение — мемоизация:
const params = useMemo(() => ({ page: 1 }), [])
useGetPostsQuery(params)
Опции хука работают совместно с middleware слоя RTK:
RTK Query автоматически предотвращает дублирование:
argПовторный вызов хука не создаёт новый HTTP-запрос, если данные уже загружаются или закэшированы.
Некоторые опции глобально настраиваются:
createApi({
keepUnusedDataFor: 30,
refetchOnFocus: true,
refetchOnReconnect: true
})
Локальные параметры хука имеют приоритет над глобальными настройками.
Изменение arg запускает полный цикл:
useGetUserQuery(userId)
Смена userId приводит к новому cache key.