Combining Reducers

combineReducers splits the state object by key and gives each key its own reducer, which sees only its own slice and cannot touch the others.

Two independent reducers sharing one storeJavaScript
import { combineReducers, configureStore } from '@reduxjs/toolkit';
const items = (state = [], action) =>
  action.type === 'cart/itemAdded' ? [...state, action.payload] : state;
const filter = (state = 'all', action) =>
  action.type === 'filters/set' ? action.payload : state;
const store = configureStore({ reducer: { items, filter } });   // combined for you
store.dispatch({ type: 'cart/itemAdded', payload: 'Mug' });
store.dispatch({ type: 'filters/set', payload: 'inStock' });
console.log(store.getState(), combineReducers({ items, filter })(undefined, {}));
Output
{ items: [ 'Mug' ], filter: 'inStock' } { items: [], filter: 'all' }

The second call shows what the combined reducer produces from nothing: each key's default. Passing an object to configureStore's reducer key calls combineReducers for you, so the explicit import is needed only when you nest: combineReducers({ user, cart: combineReducers({ items, coupon }) }) produces state.cart.items.

The combined reducer runs every child reducer on every action, so 'user/loggedOut' can empty the cart and clear the session in one dispatch with no coordination between the two files. It is cheap, because an unchanged slice keeps its old object and React 7,897 Redux 3,824 then skips the components reading it. Development enforces two rules loudly: a child reducer must never return undefined, and state keys with no matching reducer are dropped with a warning.