Back to Home
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 :
function bookReducer(prevState, action) { switch (action.type) { case "SET_TITLE": // create a new object return { ...prevState, title: action.title }; default: throw new Error(); } }
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 :
function bookReducer(prevState, action) { switch (action.type) { case "SET_TITLE": // edit the title of previous state object prevState.title = action.title; return prevState; default: throw new Error(); } }
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
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 :
function booksReducer(prevState, action) { switch (action.type) { case "SET_TITLE": // This will create a new reference. Component will rerendered return { ...prevState, title: action.title }; // This will use the previous reference. Component will not rerendered prevState.title = action.title; return prevState; default: throw new Error(); } }
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.
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