reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.69k stars 1.16k forks source link

How to set `extra` when use RTK query hooks? #4355

Closed sentoc closed 1 week ago

sentoc commented 5 months ago

Background

I'd like to determine baseUrl when make the actual api call.

baseUrl is just for example, in some cases, you may want to make the final decision when calling api, instead of at api definition time.

by reading https://github.com/reduxjs/redux-toolkit/issues/1335, I know we can use extra field, something like:

// customize a base query
export const myBaseQuery = (
  args,
  { dispatch, getState, extra },
  extraOptions,
) => {
  // determine baseUrl by `region`, which passed in via `extra`
  // we can also read config information from store via getState.
  const baseUrl = getBaseUrlByRegion(extra.region);

  // do more things with baseUrl
};

// declare myApi and endpoints
export const myApi = createApi({
  reducerPath: 'myApi',
  baseQuery: myBaseQuery,
  endpoints: builder => ({
    // getPostById only cares about `id`,
    // so I do not want to pass `region` as additional args here. 
    getPostById: builder.query<any, number>({
      query: id => ({
        url: `posts/${id}`,
        method: 'GET',
      }),
    }),
  }),
});

Question

Its ok to define apis as above, but I cannot find a way to set the extra when use query hooks, below code is what I want, but does not work, any suggestion is appreciated!

// while inside a component
// want to set `extra` when useQuery/useLazyQuery/useMutation,
// so any further calls to `getPostById` will contains the `region` information,
// but those hooks does not accept `extra` args.
const [getPostById, { data }] = myApi.endpoints.getPostById.useLazyQuery(
  { region: 'us' },  // does not work here
);

// expected clean call
const postInUsRegion = getPostById(12);

More

// unexpected, because parameter region is not part of the api. const postInSgRegion = getPostById({postId: 12, region: 'sg'})

- Also tried `dispatch`, still not able to pass `extra` in. 
```typescript
const promise = dispatch(api.endpoints.getPosts.initiate(12), { region: 'us' })
markerikson commented 5 months ago

extra comes from the global store config for the thunk middleware, so it's not something you'd be able to pass in at a hook call site.

You'd need to pass that in as one of the actual arguments to the hook (and possibly pass that value along to the base query as well - not sure).