Search code examples
reactjsreduxredux-toolkitrtk-query

How to mix RTK Query apiSlice reducers with regular RTK reducers?


I'm migrating some of our old Redux actions over from our original bespoke app to RTK Query and I've run into an issue which is likely just my lack of understanding of RTK Query.

I have an apiSlice as follows

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { AUTH_SERVER, CLIENT_ID, REDIRECT_URI } from 'app/config'

const api = createApi({
  reducerPath: 'auth',
  baseQuery: fetchBaseQuery({
    baseUrl: `https://${AUTH_SERVER}`
  }),
  endpoints: builder => ({
    tokenFetch: builder.query({
      query: ({ code, code_verifier }) => ({
        url: '/oauth/token',
        method: 'POST',
        body: {
          grant_type: 'authorization_code',
          client_id: CLIENT_ID,
          code_verifier,
          code,
          redirect_uri: REDIRECT_URI
        }
      })
    }),
    tokenRefresh: builder.query({
      query: ({ refresh_token }) => ({
        url: '/oauth/token',
        method: 'POST',
        body: {
          grant_type: 'refresh_token',
          client_id: CLIENT_ID,
          refresh_token
        }
      })
    })
  })
})

export const { useTokenFetchQuery, useTokenRefreshQuery } = api

export default api

I have three issues I can't currently figure out:

  1. I want to persist the user's auth tokens in the brower, (using redux-persist middleware in the original app - not sure how to integrate that here)
  2. I need the results of tokenRefresh to overwite the original tokenFetch api call, (currently they are stored independently) and
  3. I need to handle a tokenInvalidate action with a reducer that simply resets the auth state. (I can't see how I'd inject other reducers into this apiSlice)

How do I ensure that tokenFetch and tokenRefresh both push data to the same part of the redux state, and how do I inject a reducer in addition to the api calls to erase that state?


Solution

  • The RTK docs have an example of saving an auth token to the side with extraReducers.

    I think that shows most of what you want - saving the token to the side in an extra slice that you can manipulate at will, by using the fulfilled action of your endpoint in extraReducers.

    Also, it shows how to use that token in prepareHeaders of your baseQuery.

    In addition to that, you might want to wrap your baseQuery for automatic re-authentication.