Search code examples
typescriptreduxredux-toolkitredux-persist

How do I use persist/rehydrate in redux-toolkit?


I've setup redux-persist with react-toolkit as suggested in the documentation. Now I need to do some operation on rehydrate ow do I do that? This is what I've tried but not working.

...
import { REHYDRATE } from 'redux-persist'
...

const accessControl = createSlice({
  name: 'accessControl',
  initialState,
  reducers: {
    loginStart(state: AccessControlState) {
      state.isLoading = true
    },
    loginSucces(state: AccessControlState, action: PayloadAction<LoginResponsePayload>) {
      state.isAuthenticated = true
      state.token = action.payload.access_token
      state.isLoading = false
      state.error = null
    },
    loginFailed(state: AccessControlState, action: PayloadAction<string>) {
      state.isAuthenticated = false
      state.token = ''
      state.isLoading = false
      state.error = action.payload
    },
    logout(state: AccessControlState) {
      state.isAuthenticated = false
      state.token = ''
      state.isLoading = false
      state.error = null
    },
    [REHYDRATE]: (state: AccessControlState) => {
      console.log('in rehydrate')
    }
  }
})

Solution

  • createSlice uses the keys of the reducers object to generate action type constants prefixed by the slice name. In your case, these are strings like accessControl/loginStart and accessControl/loginFailed.

    Your rehydrate reducer isn't called because its action type constant expands to accessControl/persist/REHYDRATE, but redux-persist dispatches an action with type persist/REHYDRATE.

    To handle rehydration, you should instead write your reducer in the extraReducers object. These reducers handle external actions and don't generate actions in the slice's actions property.

    Example:

    import { createSlice } from '@reduxjs/toolkit'
    import { REHYDRATE } from 'redux-persist'
    
    const accessControl = createSlice({
      name: 'accessControl',
      initialState,
      reducers: {
        ...
      },
      extraReducers: (builder) => {
        builder.addCase(REHYDRATE, (state) => {
          console.log('in rehydrate')
        });
      }
    })