В чем разница между Redux Toolkit и Redux Query
Что проверяют
Знаете ли вы, что RTK Query не отдельная библиотека, а часть Redux Toolkit, и видите ли разницу между клиентским состоянием и серверным кешем. Следом обычно спрашивают, зачем в проекте с RTK Query ещё нужны слайсы и как обновить список после мутации.
Как отвечать
Сначала уточните: под «Redux Query» обычно имеют в виду RTK Query, который входит в пакет @reduxjs/toolkit с версии 1.6 и импортируется из @reduxjs/toolkit/query/react. Одноимённая библиотека redux-query почти забыта. Дальше разведите задачи:
- Redux Toolkit: официальный способ писать Redux.
configureStoreсразу подключает DevTools и базовые middleware,createSliceгенерирует экшены и редьюсер, Immer позволяет писать код в «мутирующем» стиле,createAsyncThunkдаёт статусыpending,fulfilled,rejected; - RTK Query: слой запросов поверх того же стора. Вы описываете
createApiсbaseQueryи эндпоинтами и получаете готовые хуки вродеuseGetUserQueryиuseUpdateUserMutation; - кеш: одинаковые запросы дедуплицируются, данные живут, пока на них есть подписчики, и по умолчанию удаляются через 60 секунд после ухода последнего (
keepUnusedDataFor); - инвалидация:
providesTagsиinvalidatesTagsсвязывают мутации с запросами, после сохранения нужные списки перезапрашиваются сами; - обновление данных:
pollingInterval,refetchOnFocusиrefetchOnReconnect(последним двум нуженsetupListeners), оптимистичные апдейты черезonQueryStartedиupdateQueryData.
Вывод: слайсы для клиентского состояния (фильтры, открытые модалки, черновик формы), RTK Query для данных с сервера. Живут в одном сторе: api.reducer и api.middleware подключаются в configureStore.
Где спотыкаются
Сравнивают их как конкурентов. RTK Query входит в Redux Toolkit, реальный выбор стоит между ним и ручной загрузкой через createAsyncThunk (или TanStack Query без Redux).
Кладут ответ сервера в обычный слайс и одновременно читают его через RTK Query. Появляются две копии данных, которые расходятся после первой же мутации.
Не настраивают теги, а после каждой мутации вручную зовут refetch() в разных компонентах. Эту работу делает invalidatesTags.