currently I'm learning NgRx. So far I learned this:
I can't really understand, why we don't directly change the state stored in the store? Why do we need this reducer and make the change on a copy of the state in the store and write it back?
For my another question here is a bit code:
import { Ingredient } from '../../shared/ingredient.model';
import * as ShoppingListActions from './shopping-list.actions';
const initialState = {
ingredients: [new Ingredient('Apples', 5), new Ingredient('Tomatoes', 10)]
};
export function shoppingListReducer(
state = initialState,
action: ShoppingListActions.AddIngredient
) {
switch (action.type) {
case ShoppingListActions.ADD_INGREDIENT:
return {
...state,
ingredients: [...state.ingredients, action.payload]
};
default:
return state;
}
}
This is a simple reducer. Here we create a new state by returning the old state and overriding the ingredients
.
Is there a pattern to follow, how we have to return the new state or it depends on the state in the store?
I think the key point that whole [action > reducer > store > selector] flow is immutability. It ensures the lack of any undesirable side effects and that your actions are predictable and repeatable.
This usually leads to improved performance and usually simpler programming and debugging.
As your application scales, the NGRX architecture will allow you to have a consistent and reliable state management.
You just have to return a new state of the store. This helps to change to ensure a "new" value is always returned. Considering your reducer's state is an object, I think a "new" state helps refresh the value of your store and allows your application to know if there is a change made in the reducer.
A direct mutation of your state would not result in this refresh as described earlier.