1
votes

I'm working on converting some older Redux code to use the new Redux Toolkit. I've run into a problem where, in the old code, multiple case statements would trigger the same reducer logic. How does one do this with the new case reducer functions?

In the old code, REGISTER_FAIL, AUHT_ERROR, LOGIN_FAIL, LOGOUT all run the same code. Is it possible to have this same type scenario in the createSlice reducers object?

Old Code

    case REGISTER_FAIL:
    case AUTH_ERROR:
    case LOGIN_FAIL:
    case LOGOUT:
      localStorage.removeItem('token');
      return {
        ...state,
        token: null,
        isAuthenticated: false,
        loading: false,
        user: null,
      };
    default:
      return state;

New Code

const authUserSlice = createSlice({
  name: 'authUser',
  initialState,
  reducers: {
    registerFail(state, action) {
      return {
        ...state,
        token: null,
        isAuthenticated: false,
        loading: false,
        user: null,
      };
    },
    registerSuccess
  },
});
1

1 Answers

5
votes

There's a couple different options.

First, you could write the case reducer functions separately, then pass them to createSlice multiple times to generate corresponding actions for each field name:

function resetState() {
  Object.assign(state, {
    token: null,
    // etc
  });
}

const authUserSlice = createSlice({
  name: 'authUser',
  initialState,
  reducers: {
    registerFailed: resetState,
    logout: resetState,
    // etc
  }
});

The other option is to use the extraReducers field, and use builder.addMatcher() to handle multiple cases with the same reducer:

const authUserSlice = createSlice({
  name: 'authUser',
  initialState,
  reducers: {
    // omit
  },
  extraReducers: builder => {
    builder.addMatcher(
      isAnyOf(REGISTER_FAIL, AUTH_ERROR, LOGIN_FAIL, LOGOUT),
      (state, action) => {
        // reset state here
      }
    )

  }
});