How to postpone refetching of invalidated RTK query
Asked Answered
T

3

7

RTK query seems to work so that when cached results get invalidated, the invalidated query is being re-fetched immediately. I would expect that a re-fetch would execute when the program requests invalidated data, but not sooner.

Real world use case

Suppose I have an app where the user needs to login - so something that majority of webapps do. Let's say I have three endpoints:

  • login mutation - logs the user in
  • getAuthInfo query - gets the authenticated session data (has providesTags: ['AuthData'] set)
  • logout mutation - logs the user out (has invalidatesTags: ['AuthData'] set)

When the user logs in, the code requests authenticated session info. And this data naturally gets cached as many pages may need certain data of this information.

But when the user later logs out, the cached data gets invalidated (as per auto-invalidation tags settings), and gets therefore immediately re-fetched by the RTK query lib. Such a call fails with HTTP 401 for obvious reasons.

Question

How can I prevent an invalidated query from being immediately re-fetched? In the upper example I would want data to be re-fetched when the code makes a new call to the endpoint but not sooner. Is it possible to control re-fetching behaviour in RTK Query?

Tench answered 24/8, 2022 at 17:48 Comment(1)
I feel like this is the use case for redux-toolkit.js.org/rtk-query/api/created-api/… where you call that when the time is right per your logic and then you make logout not automatically invalidateTagsBroccoli
B
3

The best way to invalidate tags with a delay is to use the onQueryStarted() method and combine it with a setTimeout and the api.util.invalidateTags() method from Redux toolkit.

    completeCheckListTask: builder.mutation<TaskResponse, TaskCompleteArg>({
      query: ({ body, pathParams }) => ({
        url: `checklist/${pathParams.id}/${pathParams.exampleId}/task/${pathParams.anotherId}`,
        method: 'PATCH',
        body,
      }),
      async onQueryStarted(props, { dispatch, queryFulfilled }) {
        await queryFulfilled
        setTimeout(() => {
          dispatch(api.util.invalidateTags(['Checklist']))
        }, 3000)
      },
    }),

You can read more at the docs here https://redux-toolkit.js.org/rtk-query/usage/manual-cache-updates

Banquer answered 14/10, 2022 at 0:11 Comment(1)
But that doesn't delay the fetch until it's requested the next time, but delays by a predefined amount of time which is not what I'm after.Tench
F
0

I'm using dispatch(apiSlice.util.resetApiState()) on logout, which may work for your use case.

Foreigner answered 4/1, 2023 at 14:51 Comment(0)
S
0

I would recommend to have a flag isAuthenticated and if you logged out set this flag to false. Once the user successfully logged out have a skip: !isAuthenticated for the queries that invalidated after logout.

Shoemaker answered 26/2 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.