Utilizing addMatcher with ExtraReducers for Complex Matching Logic

Showcase an advanced use case for extraReducers where addMatcher is used to apply complex action matching logic, simplifying the handling of various actions with similar characteristics.
import { createAction, createSlice } from '@reduxjs/toolkit';

// Define some action creators outside of the slice
const actionOne = createAction('action/one');
const actionTwo = createAction('action/two');

// Example of complex matching logic using a type predicate
const isActionWithId = (action) => action.payload && typeof === 'number';

// Create slice with extraReducers using addMatcher for complex logic
const mySlice = createSlice({
  name: 'mySlice',
  initialState: {},
  reducers: {},
  extraReducers: (builder) => {
    // Add a matcher to handle multiple actions with similar characteristics
      (state, action) => {
        // Assume state.entities is a map/dictionary
        const { id } = action.payload;
        if (!state.entities[id]) {
          // Initialize entity if it doesn't exist
          state.entities[id] = { data: null, loadingState: 'idle' };
        // Handle action here, e.g., set loading state
        state.entities[id].loadingState = 'loading';
    // Handle other actions as needed using standard methods
    builder.addCase(actionOne, (state, action) => { /* handle action */ });
    builder.addCase(actionTwo, (state, action) => { /* handle action */ });
This code snippet demonstrates how to use the extraReducers option inside createSlice to define complex matching logic for actions using addMatcher. It imports createAction and createSlice from Redux Toolkit, defines external actions, and sets up an isActionWithId predicate function to check if an action includes a payload with an id of type number. Within the slice declaration, addMatcher is used to apply shared logic to any action that matches the predicate. Other actions are handled individually using the addCase method.