Back to Blog

Why Redux Need Immutability

Sunday, March 7, 2021

Photo by Georg Bommeli

{{< figure src="/images/post/why-reducer-need-immutability.jpeg" caption="Photo by Georg Bommeli" >}}

When we working on a redux reducer, we need to make sure that we don't mutate the previous state object. Instead, we need to create a new object :

1function bookReducer(prevState, action) {
2  switch (action.type) {
3    case 'SET_TITLE':
4      // create a new object
5      return { ...prevState, title: action.title };
6    default:
7      throw new Error();
8  }
9}

On that reducer, if we want to set the title of the book, we need to create a new object that will spread the previous state and set the title property. So, why we dont just edit the title of the previous state object ? for example :

1function bookReducer(prevState, action) {
2  switch (action.type) {
3    case 'SET_TITLE':
4      // edit the title of previous state object
5      prevState.title = action.title
6      return prevState
7    default:
8      throw new Error();
9  }
10}

It will be easier. But, if we do it, the component that consumes that reducer will not be rerendered because redux not aware that there is an update in the state

Why Redux Not Aware of The State Update If We Just Change The Previous State?

This happens because redux using a shallow equality check to compare the previous state and the current state, this means, it just compares the reference of the state object. If it a new reference (a new object), so there is an update in the state. But if it the same reference (the same object), so the state is not changed at all. See the comparison below :

1function booksReducer(prevState, action) {
2  switch (action.type) {
3    case 'SET_TITLE':
4      // This will create a new reference. Component will rerendered
5      return { ...prevState, title: action.title };
6
7      // This will use the previous reference. Component will not rerendered
8      prevState.title = action.title
9      return prevState
10
11    default:
12      throw new Error();
13  }
14}

Why Redux Using the Shallow Equality Check?

The next question is, why redux use shallow equality check to determine if the state is changed or not? why don't just compare by its value instead (deep equality check)? If redux compares the state by its value instead of reference, it will take a longer time to determine if there is an update or not. Because it needs to check every property of the state one by one.

Summary

The reducer needs to return a new object because redux using shallow equality check, which means it check the reference of the state to determine if there is an update on the state or not. It uses the shallow equality check to make the checking process faster, so it doesn't need to compare the object by the value that needs a longer time. You can read more about it here : https://redux.js.org/faq/immutable-data