Diksha Goyal
Diksha Goyal

Reputation: 310

FetchbaseQuery invalidate cache

I have 2 completely independent components without any parent-child relationship being displayed on a single page.

Component 1 : Makes an API call fetches some records and display it in a table having server side-pagination

Component 2 : Contains a form, when the user submits the form the data in the component 1 needs to be refetch-ed through the backend.

Since I am using fetchBaseQuery to query the data, I believe I need to invalidate the cache in order to make the API call in the component 1.

I tried refetch() to fulfil that requirement but got no luck. I also tried setting the cache timeout using keepUnusedDataFor that too didn't work. Also, tried to do something with the tags, but for that I will have to use mutation instead of query and I am not sure how mutation is useful as per my use case

Here's some of the code :

component1.tsx

let { data, error, isSuccess, isError, isFetching, refetch } = useGetQuery(request, { skip});
  const records = data?.records;

 React.useEffect(() => {
    if (records) {
      // set records within table
    }
  }, [records]);

useGetQuery.ts

const extendedApi = mainApi.injectEndpoints({
  endpoints: (builder) => ({
    getQuery: builder.query<response, request>({
      query: (request?: request) => ({
        url: "someURL",
        body: request,
        method: "POST",
      }),
      providesTags: ["Requests"],
    }),
  }),
  overrideExisting: true,
});

export const { useGetQuery } = extendedApi;

component2.tsx

let [trigger, data] = useSubmitFormMutation();
const submitForm = (e) => {
    e.preventDefault();
    trigger(// Some Object);
}
React.useEffect(() => {
    if (isSuccess) {
      updateRefreshRecords(true); // setting the hook to true to make an API call in component 1
    }
  }, [isSuccess]);

useSubmitFormMutation.ts

const extendedApi = mainApi.injectEndpoints({
  endpoints: (builder) => ({
    submitForm: builder.mutation<response, request>({
      query: (request?: request) => ({
        url: "some_other_url",
        body: request,
        method: "POST",
      }),
      invalidatesTags: ["Requests"],
    }),
  }),
  overrideExisting: false,
});

export const { useSubmitFormMutation } = extendedApi;

mainAPI.ts

export const dynamicBaseQuery: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (args, api, extraOptions) => {
  const { mainApiUrl } = (api.getState() as RootState).settings.endpoints;
  const rawBaseQuery = fetchBaseQuery({
    baseUrl: mainApiUrl,
    prepareHeaders: (headers, { getState }) => {
      // Use getState to pull the jwtToken and pass it in the headers to the api endpoint.
      const { jwtToken } = (getState() as RootState).auth;
      headers.set("authorization", jwtToken);

      return headers;
    },
  });
  return rawBaseQuery(args, api, extraOptions);
};

export const mainApi = createApi({
  reducerPath: "mainApi",
  baseQuery: dynamicBaseQuery,
  endpoints: () => ({}),
  tagTypes: ["Requests"],
});

store.ts

export const store = configureStore({
  reducer: {
    // other reducers
    [localApi.reducerPath]: localApi.reducer,
    [mainApi.reducerPath]: mainApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false,
    })
      .concat(localApi.middleware)
      .concat(mainApi.middleware),
});

Can you please help me how can I invalidate the cache as per my use case.

Any help would be highly appreciated

Thanks

Upvotes: 0

Views: 701

Answers (2)

phry
phry

Reputation: 44086

You can just add invalidatesTags to your mutation and that should refresh the query:

const extendedApi = mainApi.injectEndpoints({
  endpoints: (builder) => ({
    submitForm: builder.mutation<response, request>({
      query: (request?: request) => ({
        url: "some_other_url",
        body: request,
        method: "POST",
      }),
      invalidatesTags: ["Requests"]
    }),
  }),
  overrideExisting: false,
});

No need for manual refetching or keepUnusedDataFor.

If that doesn't work, double-check that you added the api's middleware to the middlewares in your configureStore

Upvotes: 1

Sreekar
Sreekar

Reputation: 286

Simply change your submitForm endpoint to mutation type and invalidate "Requests" tag on this endpoint. This way you don't have to use updateRefreshRecords.

You can then remove below useEffect in Component1.tsx

React.useEffect(() => {
    if (refreshRecords) {
      refetch();
    }
  }, [refreshRecords]); 

and also remove keepUnusedDataFor: 5, from getQuery endpoint

I am not sure how mutation is useful as per my use case

When form is submitted, you are either creating or updating some data on backend. So, mutation is the right type of endpoint here. Use query type endpoint when you want to fetch some data from backend.

Upvotes: 1

Related Questions