configureStore ... Middleware

In development mode, the default middleware are:

ie.: const middleware = [thunk, immutableStateInvariant, serializableStateInvariant]

Note that by right, you are supposed to return a new instance of your state in your reducers. You are NOT supposed to mutate the state object in place in your reducers or through a reference of the state.


In product mode, the default middleware is:

ie.: const middleware = [thunk]
Each piece of the middleware can be configured in getDefaultMiddleware(), by either passing 'false' to get excluded, or passing the matching options object for its corresponding field.
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      immutableCheck: {
        ignoredPaths: ['ignoredPath', 'ignoredNested.one', 'ignoredNested.two'],
      },
      serializableCheck: false,      
      thunk: {
        extraArgument: myCustomApiService,
      }
    }),
})
createImmutableStateInvariantMiddleware() allows you to specify which state paths to skip checking for mutations.
mySlice-asdjk.html:
import { createSlice } from '@reduxjs/toolkit'
export const exampleSlice = createSlice({
  name: 'example',
  initialState: {
    user: 'will track changes',
    ignoredPath: 'single level',
    ignoredNested: {
      a: 'one',
      b: 'two',
    },
  },
  reducers: {},
});
export default exampleSlice.reducer;

myStore-sa90.html:
import { configureStore, createImmutableStateInvariantMiddleware} from '@reduxjs/toolkit';
import exampleSliceReducer from './exampleSlice';
const immutableInvariantMiddleware = createImmutableStateInvariantMiddleware({
  ignoredPaths: ['ignoredPath', 'ignoredNested.a', 'ignoredNested.b'],
  warnAfter?: 100,      // prints a warning if checks take longer than 100ms
  isImmutable?: IsImmutableFunc   // Callback function to check if a value is considered to be immutable. Applied recursively to every value in the state. 'true' for primitive types.
})
const store = configureStore({
  reducer: exampleSliceReducer,
  middleware: [immutableInvariantMiddleware],     //  replacing all default middleware
})
createSerializableStateInvariantMiddleware() detects if any non-serializable values have been included in the state or dispatched actions.
myConfigureStore-isdui.html:
import { Iterable } from 'immutable'
import {
  configureStore,
  createSerializableStateInvariantMiddleware,
  isPlain,
} from '@reduxjs/toolkit'
import reducer from './reducer';
const isSerializable = (value) => Iterable.isIterable(value) || isPlain(value);
const getEntries = (value) => Iterable.isIterable(value) ? value.entries() : Object.entries(value);
const serializableMiddleware = createSerializableStateInvariantMiddleware({
   isSerializable,         // The function to check if a value is considered serializable. This function is applied recursively to every value contained in the state. Defaults to `isPlain()`.
   getEntries,             // The function that will be used to retrieve entries from each value.  If unspecified, `Object.entries` will be used. Defaults to `undefined`.
   // ignoredActions,      // An array of action types (strings) to ignore when checking for serializability. Defaults to [].
   // ignoredActionPaths,  // An array of dot-separated path strings to ignore when checking for serializability, Defaults to ['meta.arg', 'meta.baseQueryMeta'].
   // ignoredPaths,        // An array of dot-separated path strings to ignore when checking for serializability, Defaults to [].
   warnAfter: 100,         // Warns if checking takes longer than 100ms. Defaults to 32.
   // ignoreState: true,   // Opt out of checking state. When set to `true`, other state-related params will be ignored.
   // ignoreActions: true  // Opt out of checking actions. When set to `true`, other action-related params will be ignored.
});
const store = configureStore({reducer, middleware: [serializableMiddleware]}));