Blog>
Snippets

Reusing Reducers with createReducer

Exemplify the use of `createReducer` for reusing reducer logic across different features without duplicating code.
function createReducer(initialState, handlers) {
  // A utility function to create a reducer
  return function reducer(state = initialState, action) {
    if (handlers.hasOwnProperty(action.type)) {
      // Call the corresponding handler function for the action type
      return handlers[action.type](state, action);
    }
    return state;
  };
}
This is the createReducer utility function that simplifies the creation of a reducer for handling different action types. It takes an initial state and an object with handler functions for each action type.
const addTodoHandler = (state, action) => [
  ...state,
  {
    id: action.id,
    text: action.text,
    completed: false
  }
];

const toggleTodoHandler = (state, action) => state.map(todo =>
  (todo.id === action.id ? { ...todo, completed: !todo.completed } : todo)
);
These are specific handler functions that can be reused across different reducers. 'addTodoHandler' handles adding a new TODO item, whereas 'toggleTodoHandler' toggles the completed state of a TODO item.
const todosInitialState = [];
const todosHandlers = {
  ADD_TODO: addTodoHandler,
  TOGGLE_TODO: toggleTodoHandler
};
const todosReducer = createReducer(todosInitialState, todosHandlers);
Here we're creating a 'todosReducer' by calling the 'createReducer' utility, passing in the initial state and the handlers object for managing TODOs. This reducer will now handle 'ADD_TODO' and 'TOGGLE_TODO' actions with the provided handler functions without any duplication of code.
const goalsInitialState = [];
const goalsHandlers = {
  ADD_GOAL: addTodoHandler, // Reusing addTodoHandler for a different feature
  COMPLETE_GOAL: toggleTodoHandler // Reusing toggleTodoHandler for a different feature
};
const goalsReducer = createReducer(goalsInitialState, goalsHandlers);
In this example, we're reusing the 'addTodoHandler' and 'toggleTodoHandler' to create a 'goalsReducer' for managing goals. We pass a different initial state and map the handlers to different action types.