rtk-query

Add delay before invalidate tags in Mutation and sync with isLoading state


I'm using Redux-Toolkit (RTK) Query and have a scenario is when trigger a mutation, need to delay for a specific time before refetch another query (invalidate tags).

It can be solved with some things like:

onCacheEntryAdded: async (args, { cacheEntryRemoved, dispatch }) => {
  await waiting(5000);
  await cacheDataLoaded;
  dispatch(api.util.invalidateTags([
    MISSION__GET_LIST_MISSION_DETAIL__TAG
  ]));
  await cacheEntryRemoved;
},

But, in that solution, I cannot use the isLoading build-in state of the mutation because those states don't sync with the custom life cycle (mutation state success before await cacheDataLoaded).

const [updatePost, { isLoading }] = useUpdatePostMutation()

So is there any way to solve this instead of handling more extra complex logic outside of the mutation (define custom state and mutate in lifecycle, in extraReducer,... )?


Solution

  • You cannot interfere with the handling process in onQueryStarted because it is only used to listen to events.

    You can use transformResponse to delay the result as desired.

    export const apiSlice = createApi({
            reducerPath: "api",
            baseQuery: fetchBaseQuery({ baseUrl: "https://jsonplaceholder.typicode.com/" }),
            tagTypes: ["Post"],
            endpoints: (builder) => ({
                getPosts: builder.query({
                    query: () => "posts",
                    providesTags: ["Post"],
                }),
                addPost: builder.mutation({
                    query: (newPost) => ({ url: "posts", method: "POST", body: newPost }),
                    transformResponse: async (response) => {
                        await waitForMs(5000);
                        return response;
                    },
                    onQueryStarted: async (_, { dispatch, queryFulfilled }) => {
                        await queryFulfilled;
                        dispatch(apiSlice.util.invalidateTags(["Post"]));
                    },
                }),
            }),
        });