How to invalidate RTK query caches(reset state) globally?
Asked Answered
B

3

27

Project uses redux toolkit and rtk query. Data are fetched from one api, but the code is split into smaller chunks to reflect logical parts like

  • /vehicles
  • /users
  • /settings

...etc

After logout rtk query preserves its state, so on next login the data are old. They might not even reflect the current user. How can I invalidate all the caches?

Beadledom answered 22/3, 2022 at 13:57 Comment(0)
B
42

Actually it is pretty simple, but I had to refactor the code.

I created new api for each logical part. So to invalidate cache I would have to reset each api's state individually.

Fortunately rtk has code splitting capabilities in it: https://redux-toolkit.js.org/rtk-query/usage/code-splitting

Basically you create baseApi likes this:

export const baseApi = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: `${BASE_URL}/api`,
    prepareHeaders: (headers, { getState }) => {
      const token = (getState() as RootState).auth.token;
      if (token) {
        headers.set("authorization", `Bearer ${token}`);
      }
      return headers;
   },
  }),
  tagTypes: ["Vehicle", "CompanySetting", "Associate"],
  endpoints: () => ({}),
});

Then you can add api slice to it in a separate file, like so:

export const companySettingsApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    getCompanySettings: builder.query<CompanySetting[], void>({
      query: () => ({
        url: `/companySettings`,
      }),
      providesTags: (_) => ["CompanySetting"],
    }),
    setCompanySettings: builder.mutation<void, CompanySetting[]>({
      query: (companySettings) => ({
        url: `/companySettings`,
        method: "PUT",
        body: companySettings,
      }),
      invalidatesTags: (_) => ["CompanySetting"],
    }),
  }),
});

This gives you ability to reset entire api state with a single dispatch

dispatch(baseApi.util.resetApiState());
Beadledom answered 22/3, 2022 at 13:57 Comment(5)
That is also one of the reasons why we are very adamant in the docs that you usually should just have one api ;)Amandaamandi
Also, please note that if you use redux-persist to persist api state that you also have to rehydrate it according to redux-toolkit.js.org/rtk-query/usage/…Amandaamandi
Tags invalidation is not work because it not clears cache, so user dependent data still available after that, even after data refetch and receiving 4XX status code. api.util.resetApiState only can help, but it forces all cache data to be cleared.Dumpcart
Thanks for this answer, I've been scratching my head around this for a while.Birth
Thank you for this. I've been messing around with having created different APIs for my types. Putting them in 1 single baseApi made it possible to invalidate caches between them. Finally!Dirham
P
22

SOLUTION: This will immediately remove all existing cache entries, and all queries will be considered 'uninitialized'. So just put the below code into onClick or according to your scenario so when you hit an enter request will go and cache would also be clear. Below here api is your name of an api which you would set in your rtk query in store.

dispatch(api.util.resetApiState());

For more info please have a look in documentation https://redux-toolkit.js.org/rtk-query/api/created-api/api-slice-utils

Panhellenism answered 30/8, 2022 at 10:56 Comment(2)
so we need to do this for all API's we have ?Thoer
@BryanLumbantobing yes you need to do this for API’s for which you don’t want to store data in cache and everytime query will fetch results from an API. It depends on your usecase, sometimes we don’t need it.Panhellenism
C
16

In case you need to reset only specific cache, for example CompanySettings, you can also use:

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

Documentation https://redux-toolkit.js.org/rtk-query/api/created-api/api-slice-utils#invalidatetags

Collative answered 5/11, 2022 at 11:44 Comment(3)
That's the one I looked for)Hipped
Does this automatically then refetch the new data for API with the tag CompanySettings ?Lanza
@Karan Shah, yesJoell

© 2022 - 2024 — McMap. All rights reserved.