Complex Reducers

Learn how to create, manage, and refactor complex reducers.

Complex state management using Redux in a simple to-do app

To understand Redux in the context of a much larger state, let’s look at a more realistic example. The upcoming example describes a simple to-do app, and we’ll look at how to implement state management for this app. The to-do app will manage lists of to-do items and also contain a logged-in user area. The state will consist of two top-level properties:

  1. todos (of type array)
  2. user (of type object)

This is reflected in our current state:

const initialState = Object.freeze({
  user: {},
  todos: [],
});

To ensure that a new state object is being created instead of mutating the previous object, the initial state object is wrapped by Object.freeze(). If there is an attempt to mutate the **state object **directly, a TypeError will be thrown:

Press + to interact
'use strict';
const initialState = Object.freeze({
user: {},
todos: [],
});
initialState.user = 'Lets change this state';

Let’s have a look at how a reducer function that manage the to-dos—meaning adding, removing, and changing the status of to-do items—and set the login area of a user:

Press + to interact
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_USER': {
return {
user: {
name: action.payload.name,
accessToken: action.payload.accessToken,
},
todos: state.todos,
};
}
case 'ADD_TODO': {
return {
user: state.user,
todos: state.todos.concat({
id: action.payload.id,
text: action.payload.text,
done: Boolean(action.payload.done),
}),
};
}
case 'REMOVE_TODO': {
return {
user: state.user,
todos: state.todos.filter((todo) => todo.id !== action.payload),
};
}
case 'CHANGE_TODO_STATUS': {
return {
user: state.user,
todos: state.todos.map((todo) => {
if (todo.id !== action.payload.id) {
return todo;
}
return {
...todo,
done: action.payload.done,
};
}),
};
}
default: {
return state;
}
}
};
const store = createStore(rootReducer);

We won’t go into too much detail. However, a few things should be explained in depth. Let’s look at each switch block, in which each ...