Introduction to State Management in Angular v2+
In this article, we will learn about state and state management in Angular v2+. There will be a following article about how to implement state management in Angular v2+ with extensions such as @ngrx/store and @ngrx/effects.
State
We should begin with explaining the state which might be a mystical term for the beginners. “State” term includes both the state of UI and the state of variables in your code. So any change in your application changes the state.
In Angular or other modern JS frameworks, each component has its own state and a component has no idea about the other components’ states unless we make enable the data flow between components. We use @Input and @Output decorators to pass information between parent and child components in Angular v2+.
It is easy to pass information between components in simple apps. But it gets complicated and painful when you have complex app architecture like the figure below.
Let’s think about how to pass data between Component 2 and Component 6. If you use @Input/@Output it takes 4 hops to get Component 6 from Component 2 and the you should involve the other 3 components in this process.
State Management
We should mention about Redux at this point. Redux is an elegant solution architecture which simplifies the state management.
There are three core principles in Redux architecture;
- Single Store: state of the application should be stored in a single “store”. Store is the only responsible in providing data to components. Data flows between component and Store instead of component-to-component.
- Read-only state: state should be read-only or immutable. To change the state, new action should be emitted.
- Pure function reducers: Reducers take the current state and an action and return next state. Reducers should not take any other parameters outside the function.
Another important point of Redux is that all data in the application flows only one-way, in other words data flow is unidirectional. Data flow in an application can be seen from the figure below.
- Component dispatches an action
- Reducer in the store takes the action and produces a new state
- New state pass to the component from Store.
@ngrx/store
@ngrx/store is a state management extension for Angular applications inspired by Redux. It imports all core concepts from Redux. From now on, we will use @ngrx/store terms instead of Redux.
Store
Store is the core structure where actions, reducers and state are located. The store receives actions as inputs, and transmit actions to reducers. Reducers produce a new state depending on the action and emit the new state. The store holds the new state until it changes via another action.
Action
An action consists of two parts, type and payload. Type is required to make reducer enable to distinguish the actions. Therefore type must be unique for each action.
Reducer
The reducer is the core element in the tore and it is the responsible for changing the state. A reducer takes action and current state as input parameters and returns a new state according to the function inside it.
(The state is immutable in Redux architecture, so the reducer does not mutate the state but produces a new one.)
Let’s create a simple reducer with the actions defined previously.
When a reducer is called upon a new action, it checks the type of the action and return new state according to action type. As stated previously, reducers must be pure functions.
Why @ngrx/store?
As it’s been seen obviously, Redux or @ngrx/store is in some sense the hardest way to do simple tasks. If you have a simple todo application with Angular, it is not suitable to use @ngrx/store in it because of heavy overhead in the code. However, it gets more meaningful to implement @ngrx/store in your Angular app when the application goes complex.
In the next article we will dive into the implementation of @ngrx/store into an Angular application and we will see how to improve performance by using @ngrx/store.
Further Reading:
Redux-Predictable state container for JavaScript apps
Comprehensive Introduction to @ngrx/store
From Inactive to Reactive with ngrx Brandon Roberts & Mike Ryan