I'm looking at this Redux tutorial where the following reducer is being discussed:
function visibilityFilter(state = 'SHOW_ALL', action) {
return action.type === 'SET_VISIBILITY_FILTER' ?
action.filter :
state
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{
text: action.text, completed: false
}]);
case 'TOGGLE_TODO':
return state.map((todo, index) =>
action.index === index ?
{ text: todo.text, completed: !todo.completed } :
todo
)
default: return state;
}
}
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
};
}
What it does it clear, however I don't get why it does the state.concat
/ state.map
to duplicate the state instead of working on it directly. I understand it's to achieve immutability, but, technically, what could go wrong if I change the code from this:
return state.map((todo, index) =>
action.index === index ?
{ text: todo.text, completed: !todo.completed } :
todo
)
to this:
state[action.index].completed = !state[action.index].completed;
return state;
The state that was passed to the reducer is obsolete anyway, so whether it has been changed or not it must not be used anywhere (and if I'm not mistaken that's indeed what Redux is doing - it ignores the previous state and takes the new one as the "source of truth"). So only the new state returned by the function should matter.
So if I follow this approach of modifying the state directly in the reducer and returning this, what bug could that create in my application? Any idea?