Created by Dan Abramov, Redux is an application architecture pattern based on Flux ideas and simplified with concepts from Elm. Redux gives you the power to build consistent applications and to control the way your data flows and is transformed, following three principles:
1. Single Source of Truth
The entire state of your application is stored in an object tree within a single** **store. Any access to the state is done by referencing the original data, in the store. This way, when information is updated it gets propagated throughout the application, thus preventing duplicate data.
2. State is Read-only
The only way to change the state of your application is by emitting an action, an object that describes what happened.
To access the state you can use the method getState from the store. It returns the whole application state, but as read-only.
To listen to changes on the state we use the store’s method subscribe, and pass a listener as a parameter in the following way:
As we can see in the above example, when we want to cancel the listener we just call the value returned from the method subscribe, as a function.
When we need to modify the state, the change needs to be requested by an action, an object containing a type **(required) and a **payload **(optional). The **type is an identifier for the action and the payload is the content to be sent with the action, as seen in the following example:
In the example above, the action has type ADD_CONTACT and the necessary data to include this contact in the state.
It’s common to create actions using action creators, which are functions that expect specific parameters and return a formatted object, as in the following example:
To dispatch an action, we use the method dispatch from the store:
3. Changes are made with Pure functions
To describe the way the state will be changed by the actions, we write pure reducers.
Reducers are functions that are called every time an action is dispatched. They receive the current state and the action as parameters, and return the new state.
It’s important to highlight that a reducer must be a pure function. Given the same parameters, a reducer should always return the same result, and to do that, it has to be based on its own scope.
Considering our reducers must be pure functions, we are going to implement our logic to include a new contact in the state.
As we can see in the above example, our reducer checks if the action is of type ADD_CONTACT. If it is, it returns a new state, including the new contact.
To get the most out of Redux, **you must understand the concept of immutability. In the above example, we don’t use the **push **method to include the new contact in the **contactCollection, instead, we return a new contactCollection. This one has the same contacts as the previous collection, but contains the new contact. This way we preserve the previous state and stay in the premise of read-only state.
By following these three principles, you can write a predictable application very easily.
In this post, we only scratched the surface of Redux. In the next posts, I intend to go deeper in each concept.
At the beginning, Redux can seem a little complicated because it is different from what we are used to. Nevertheless, as soon as you learn the basics, the sky is the limit.
Did you enjoy the post and think it’s useful? Share this article, to help us spread the word :)