Как решать проблемы с кешированием в RTK

Ответ

В RTK Query проблемы с кешированием чаще всего возникают из-за неверных тегов или отсутствия инвалидации. Вот основные подходы:

  1. Теги (tags) - помечайте данные тегами для автоматической инвалидации:
// В API
tagTypes: ['Posts'],
endpoints: (builder) => ({
  getPosts: builder.query({
    query: () => '/posts',
    providesTags: ['Posts']
  }),
  addPost: builder.mutation({
    query: (post) => ({
      url: '/posts',
      method: 'POST',
      body: post
    }),
    invalidatesTags: ['Posts']
  })
})
  1. Ручная инвалидация через invalidateTags:
dispatch(api.util.invalidateTags(['Posts']))
  1. Параметры кеширования - настройте keepUnusedDataFor и refetchOn... в API:
// В createApi
keepUnusedDataFor: 30, // время в секундах
refetchOnMountOrArgChange: true
  1. Принудительный рефетч через refetch() из хука запроса

Для сложных случаев используйте api.util.selectInvalidatedBy для точного контроля инвалидации.

Ответ 18+ 🔞

О, слушай, с RTK Query такое бывает — вроде всё настроил, а кеш ведёт себя как последняя мартышлюшка, блядь. В основном вся хуйня происходит из-за тегов, которые забыли проставить, или инвалидация не срабатывает. Давай разберём, как с этим бороться.

Теги (tags) — твои лучшие друзья, ёпта.
Помечай данные тегами, чтобы запросы сами инвалидировались, когда что-то меняется. Вот смотри, как это выглядит:

// В API
tagTypes: ['Posts'],
endpoints: (builder) => ({
  getPosts: builder.query({
    query: () => '/posts',
    providesTags: ['Posts'] // Говорим: "Эти данные относятся к тегу 'Posts'"
  }),
  addPost: builder.mutation({
    query: (post) => ({
      url: '/posts',
      method: 'POST',
      body: post
    }),
    invalidatesTags: ['Posts'] // А тут: "После этого мутатора всё с тегом 'Posts' — в топку!"
  })
})

Ручная инвалидация, если автоматическая не дожала.
Иногда нужно вручную ткнуть систему, мол, "эй, обнови эту хуйню!". Используй invalidateTags:

dispatch(api.util.invalidateTags(['Posts']))

Параметры кеширования — тонкая настройка, блядь.
Можно поиграть с keepUnusedDataFor и refetchOn... прямо в настройках API:

// В createApi
keepUnusedDataFor: 30, // данные висят в кеше 30 секунд после того, как компонент отписался
refetchOnMountOrArgChange: true // рефетч при монтировании или изменении аргументов

А если совсем припёрло — принудительный рефетч.
Из хука запроса можно дернуть refetch() и сказать: "Ну-ка, обновись, сука!"

const { data, refetch } = useGetPostsQuery();
// Где-то в обработчике:
refetch();

Для особо изощрённых случаев есть api.util.selectInvalidatedBy — инструмент для точного, хирургического контроля над инвалидацией. Когда нужно понять, что именно пора обновить, а не просто накрыть всё медным тазом.

Вот и всё, ёпта. Главное — не забывай про теги, а то будет как у того Герасима: "Муму-муму", а нихуя не работает.