Search code examples
reduxredux-toolkitrtk-query

RTK Query: Set baseUrl from store


I have an app that contains a store:

const initialState: GlobalState = {
  data: {
    isOnboardingCompleted: 'unknown',
    isEnvironmentReady: false,
    environmentConfig: ProdEnvConfig,
    // ...
  },
}

The key environmentConfig contains an object where the baseUrl is stored. The environment config can change while the app is running. User is able to select different ones.

When creating my api:

export const BaseApi = createApi({
  reducerPath: 'base-api',
  baseQuery: fetchBaseQuery({
    baseUrl: '',
  }),
  endpoints: builder => ({
    getStudents: builder.query({
      query: param => {
        return "/students"
      },
    }),
  }),
});

How can I set the baseUrl while also listening to changes to environmentConfig and re-setting the baseUrl from the store?

I am imagining some pseudo-code like this which I can't seem to make work:

const listen = () => {
  const config = store.getState().global.data.environmentConfig

  BaseApi.setBaseUrl(config.baseUrl)
}

store.subscribe(listen)

Any ideas on how to achieve this?


Solution

  • I believe you could write a small wrapper around the fetchBaseQuery function and pass in a baseUrl that is stored in the Redux store.

    Example:

    import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
    
    const baseQuery = (baseQueryArgs = {}) => async (
      fetchArgs = {},
      api,
      extraOptions = {},
    ) => {
      const { getState } = api;
      const state = getState();
      const baseUrl = state.baseUrl;
    
      return fetchBaseQuery({
        ...baseQueryArgs,
        baseUrl,
      })(fetchArgs, api, extraOptions);
    };
    
    export const BaseApi = createApi({
      reducerPath: 'base-api',
      baseQuery: baseQuery(),
      endpoints: builder => ({
        getStudents: builder.query({
          query: param => {
            return "/students"
          },
        }),
      }),
    });