Кэш в RTK Query построен как детерминированная система хранения результатов запросов, где каждая комбинация endpoint + аргументы формирует отдельную запись в хранилище. Такой подход исключает необходимость ручного управления состоянием загрузки данных и позволяет библиотеке автоматически контролировать жизненный цикл данных.
В основе кэша лежит понятие уникального ключа запроса. RTK Query формирует его из двух компонентов:
Каждый вызов useQuery или
store.dispatch(api.endpoints.xxx.initiate()) приводит к
вычислению этого ключа. Даже незначительное отличие в аргументах создает
новую запись в кэше.
Это означает:
getUser({ id: 1 }) и getUser({ id: 2 }) —
разные сущности кэшаСистема кэширования не пытается «понимать» семантику данных, она опирается исключительно на структурное сравнение входных параметров.
Внутренне RTK Query хранит данные в отдельном reducer-срезе, обычно
называемом api. Его структура включает несколько
уровней:
queries — данные конкретных запросовmutations — состояние мутацийprovided / subscriptions — связи между
запросами и компонентамиКаждая запись в queries содержит:
data — результат запросаstatus — состояние загрузки (pending,
fulfilled, rejected)endpointNamerequestIdfulfilledTimeStamperror (если есть)Эта структура позволяет одновременно хранить несколько версий одного endpoint с разными аргументами без конфликтов.
Одним из ключевых механизмов является система subscriptions. Каждый компонент, использующий хук запроса, создает подписку на конкретный cache key.
Если несколько компонентов используют один и тот же запрос:
Когда последний подписчик размонтируется:
keepUnusedDataFor данные удаляются из
кэшаЗначение keepUnusedDataFor определяет, сколько времени
данные остаются в памяти после потери всех подписок. Это предотвращает
как преждевременное удаление, так и бесконечное накопление данных.
RTK Query предотвращает повторное выполнение одинаковых запросов, если:
В таком случае новые подписчики не инициируют сетевой запрос, а подключаются к уже существующему.
Это достигается через:
requestId для каждого выполненияТаким образом, даже при множественных вызовах одного endpoint сеть не перегружается дублирующими запросами.
Кэш в RTK Query не является статичным. Он управляется через систему tag-based invalidation.
Каждый endpoint может:
providesTags)invalidatesTags)Когда происходит мутация:
Пример логики:
getPosts предоставляет тег PostsaddPost инвалидирует тег PostsgetPosts пересчитываютсяВажно, что инвалидируется не весь кэш, а только связанные записи, что делает систему точечной и эффективной.
При повторном использовании одного и того же запроса RTK Query учитывает несколько факторов:
refetchOnMountOrArgChangeЕсли данные присутствуют и считаются актуальными, библиотека:
Если данные устарели или принудительно настроено обновление:
Система очистки кэша работает по принципу отложенного удаления. После исчезновения последнего подписчика:
Если в течение этого времени запрос снова становится активным:
Такой подход снижает количество повторных сетевых запросов при частом монтировании/размонтировании компонентов.
В отличие от Redux Toolkit Entity Adapter, RTK Query не использует полноценную нормализацию данных.
Кэш устроен как:
Это означает:
Преимущество такого подхода — простота и предсказуемость. Недостаток — невозможность автоматически синхронизировать одинаковые сущности между разными запросами без использования тегов или ручных механизмов.
RTK Query поддерживает несколько механизмов повторного получения данных:
refetchOnMountOrArgChangerefetchOnFocusrefetchOnReconnectpollingIntervalКаждый из этих механизмов взаимодействует с кэшем независимо, но всегда опирается на один и тот же cache key.
Например:
reconnect) проверяются все
активные подпискиКаждая запись кэша содержит метку времени
fulfilledTimeStamp. Она используется для определения:
RTK Query не использует сложную модель «stale-while-revalidate» как отдельный режим, но реализует его поведение через комбинацию:
Таким образом достигается баланс между скоростью интерфейса и актуальностью данных.
Мутации в RTK Query не только отправляют данные на сервер, но и напрямую влияют на кэш.
После успешной мутации возможны сценарии:
updateQueryDataОсобенность системы в том, что кэш является единственным источником данных для UI, поэтому любое изменение сразу отражается в интерфейсе без дополнительных синхронизаций.
При оптимистическом обновлении RTK Query:
patchЭто возможно благодаря тому, что кэш хранит не только данные, но и историю изменений через undo-логи внутри middleware механизма.
Каждый endpoint имеет собственное пространство внутри кэша. Это исключает конфликты между разными типами запросов, даже если они возвращают схожие структуры данных.
Например:
getUsergetUserPostsбудут храниться независимо, даже если оба возвращают объект пользователя.
Внутренняя модель RTK Query объединяет несколько принципов:
Все эти механизмы формируют кэш как реактивный слой между серверными данными и UI, где каждое изменение состояния определяется не вручную, а через события запросов, подписок и мутаций