Redux has three core principles as described by his co-author Dan Abramov, and the first step to becoming a Redux expert is to fully understand them. In this post we are going to explain each one of them in detail.
To picture the basic principles of Redux better, we are going to use a simple Pizza Calculator App. The inputs for our application will be the number of guests that we will have at our party and the calculator will tell us how many pizzas we need to buy. It is a very simple example, but it can help us perfectly picture the principles of Redux with it. Keep in mind these principles will stay the same as your application grows bigger and more complex.
Principle #1: Everything is contained in a single object
The only things that can change over time in our app are
number of people and
number of pizzas. The first one is input by the user and the second one is calculated by the app. Those are the two values that we are going to store in our State tree. With the current implementation we could have
number of pizzas directly in the State of the Component, but for the sake of this example we are going to keep it in the State Tree.
This is the whole State of our application, kept in a single object in the Redux store that you can grow as large as your application needs it.
Principle #2: The State Tree is read-only
Here is where the concept of an
action comes in. Every time that you want to modify the State of your application, you need to dispatch an action, which will describe the change that is about to happen.
type property with a value assigned different than
undefined. It is recommended that you use a string, and it should be as descriptive as possible. It helps a lot when you are debugging your application.
To picture this better, I wrote a simple
logger.js file which logs the current State to the console, the action describing the change to be made to the store (action), and the State after the action was dispatched. For now, we will only see the action.
In the action depicted in the previous image, we can see that the type is
UPDATE_NUMBER_OF_PEOPLE, which is a short description of how the State will change, and then the payload has the value
"6". By reading the action object it is easy to infer that the number of people invited to our party will be 6.
Actions are the only way that we can change our State Tree, there is no other way. The State is read-only, we can't modify it directly.
It is important to know that it is a good practice to make only one change to your State Tree per action. This way it is easier to track what is happening in our application which can also help prevent bugs.
Principle #3: The Reducer must be a pure function
The reducer is a pure function that you need to write and will be used by Redux to calculate your next State object based on two parameters, an
action describing the change to be made and the previous State.
A pure function is a "reliable" function that always returns the same result if the input is the same, without observable side effects
This pure function called reducer does not mutates the State. This means that every time you dispatch an action, Redux returns an entirely new State, regardless of how many properties the actions has changed. This process is always the same, no matter if your application is a "Pizza calculator" or a much more complex one.
If you are wondering if it is expensive to calculate the whole State of your app in a single function every time that there is a change, it is not! For example, if I change the number of people in my app, I have to create a new object for the State, but I can keep the reference to the previous version of the number of pizzas, because it has not changed when I changed the number of people. This is what makes Redux fast.
This is an example of how Redux calculates our next State. We need to send to our reducer an action and the previous State. At doing this, Redux knows that the number of Pizzas will not change, it will remain as 4, but what it needs to change is the number of people, and its new value will be 13.
These are the three basic principles of Redux
- Everything is contained in a single State object
- The State tree is read-only
- The Reducer must be a pure function
It is important to master these concepts in order to understand and build an efficient Redux application. As long as you follow these principles, you will have a solid Redux foundation to start building more complex applications.