Search code examples
javascriptreactjsreact-reduxredux-toolkitrtk-query

Redux query multiple createApi & reducerPath with refetching


My application has to fetch data from 3 different servers, they are all connected to the same DB. Thus I have split the code into 3 different createAPIs and used different reducer paths, however, it seems like I cannot use refetching if I do an edit PUT from API A but API B also needs a refresh.

I cannot change the layout of the servers since this is our backend server architecture.

export const commonApi = createApi({
  reducerPath: "commonApi",
  baseQuery: commonBaseQuery, //URL: common.dev.example.com
  endpoints: () => ({}), //later injected
  tagTypes: ["SCHEME_LIST", "SCHEME_DETAIL"],
});

export const taskApi = createApi({
  reducerPath: "taskApi",
  baseQuery: taskBaseQuery, //URL: task.dev.example.com
  endpoints: () => ({}), //later injected
  tagTypes: ["LIST", "DETAIL"]
});

export const addressApi = createApi({...}) // omitted, same as above with different url

Now, if I use a mutation query editTask from taskAPI. It needs to update getTaskList, getTaskDetail from taskAPI. By using invalidatesTags: ['LIST', 'DETAIL'] I can automatically get the changes.

However, during this editTask, an API getWarehouseList from commonAPI also needs to be updated to reflect some changes. I cannot use tags anymore since they don't belong to the same createApi/reducerPath

The question is how would I update this getWarehouseList from commonAPI when editTask from taskAPI makes a change? Or the only way is to do a unwrap().then() and just manually refetch this data?


Solution

  • You can use the invalidateTags API slice utility to invalidate any specific tags you like. How it can be used is the mutation endpoints in commonApi can invalidate specific tags in taskApi, and vice-versa. I'd suggest using the mutation endpoint's onQueryStarted handler to do this.

    Example:

    taskAPI slice

    ...
    editTask: build.mutation({
      ...
      onQueryStarted: async(arg, { dispatch, queryFulfilled }) => {
        try {
          await queryFulfilled;
          dispatch(commonAPI.util.invalidateTags(
            ["SCHEME_LIST", "SCHEME_DETAIL"] // or whatever you specifically need
          ));
        } catch(error) {
          // handle/ignore/etc
        }
      },
    }),
    ...
    

    For what it's worth, using unwrap().then() in the UI code could also work, though I'd still suggest manually invalidating the tags versus manual refetching. Something like the following:

    try {
      await editTaskTrigger().unwrap();
      dispatch(commonAPI.util.invalidateTags(["SCHEME_LIST", "SCHEME_DETAIL"]));
    } catch(error) {
      ...
    }