Why do we even need Redux for? The answer is to manage state of our application. State management in React can be a very tricky thing, especially when we need to pass data from a root element to a heavily nested element. As React has a one-way data flow, that means we can only pass data in one direction, we can only pass data from parent to child component. That’s why a lot of times we pass data to a component that it doesn’t even need.
Here, If the parent component has some data that ChildC needs, we need to pass the data to ChildA and then ChildB, and then from ChildB to ChildC. Here, ChildA and ChildB are simply used as a medium.
Personally, I have faced this issue since the day I started to code in React. This is completely fine in some cases, but in others, it adds redundancy to our application. Every component that consumes or uses these providers is re-rendered whenever there is a state change.
So, how do we solve this issue? There are many ways to do it, like lifting state up, Context API, Redux, etc. But the solution I found most comfortable for me is Redux. In this article, we will learn about Redux in a simplified way.
When it comes to learning front-end development, few tools cause more headaches than Redux. It is arguably one of the trickiest parts for sure. It may seem intimidating at first but, like most tricky parts of web development, It gets a lot easier with practice. For most learners, It may take some time to figure out. Be prepared to give it a bit of thought haha!
What is Redux?
Redux is a state container. It is probably the most popular global state management library for react by far.
It is most commonly paired with React, where it takes control of states away from React components and stores them in a place called a ‘store’.
So, It becomes very easy to access any state from any component in the application, as all the states are stored in a global store. It has a lot of boilerplate code and seems overworking for just increasing/decreasing a value.
Before jumping right into the code, let’s just see the workflow of Redux, though it might not make any sense to you now.
I mean it kind of looks scary right? Let’s look into a more simplified version of it first.
We have a State which is a value we have (suppose, 0 initially). If we want to change the value we need to invoke an action. Like, If we want to change the value we need to increment it or decrement it in some way. That is called action. After invoking the action, we see the changed value in our browser, which is called View.
The basic concept of Redux is it, precisely!
Alright, now let’s learn more about the whole workflow of Redux. Let’s get back to the previous photo.
Store: An object where the application state lives. It is the singular point of states. The store brings everything together.
Action: The actual action we want to take place, for example, “add one”. An object that contains the type of the action (event) and a payload that is optional.
What we are seeing above is an Action. But we normally use Action Creator which returns an Action. It is useful to create dynamic actions. An action creator looks like this:
Reducer: Reducer specifies how the application’s state should change in response to each action. For example, our new state should be one integer higher than our old state.
It is a function that takes two arguments (currentState, action) and, depending on the action type (e.g., add or remove), will make a new state with the new changes and return the new state.
I mean we learned the definition of Redux workflow elements. But let’s put it into practice. That’s how we actually learn right?
We will build a counter using Redux. I know it is pretty common but our main purpose in this article is to understand Redux workflow. Let’s dive into that.
Step 1: Install Redux
npm install redux react-redux
Step 2: Create Store and Reducer
We know that we need to configure the store for Redux, that’s where all the states will be stored. Although it’s actually up to you how you want to configure it. But I like it this way.
Like the code above, we will create a store by using the createStore method from redux and then export it. Now you might be wondering what is the reducer inside the createStore method!
Let’s create it. In this INITIAL_STATE object below, we will initialize our state. As we want to increment/decrement a value, that’s why we initialized a count variable with 0 as the value.
Now, reducer will be a function that takes the state object we initialized and actions that will modify the state as parameters. In the switch case, we will be adding those actions and their consequences later. But let’s create those actions first.
Step 3: Creating Actions
As I mentioned above, that Action is an object that contains the type of the action and a payload which is optional. Let’s create a file named actions. Here we don’t need any payload, because we are not sending any value to the store, we are only increasing/decreasing a value.
We wrapped the action inside action creators. Here is the incrementCounter action creator.
Here is the decrementCounter action creator.
Our whole actions file will look like this below –
Now we have created actions, we will be editing the Reducer to implement modifications when our action is dispatched or invoked.
Let’s modify the Reducer. In the switch case, for “INCREMENT” action, we will increase the count value by 1, and for “DECREMENT” action, we will decrease the count value by 1. Like this picture below:
Creating action, reducer and store is completed. Now, we need to wrap our store in index.js file with our App component like this.
Redux setup is completed, Now we need to connect our UI with it.
Step 4: Connecting State & Actions with UI/Component
The final part is to see our state and invoke action from the UI to see the updated value.
here, we import the connect function from the react-redux library, we also import our increaseCounter and decreaseCounter actions.
Check the last line of the file where we export the component, we can see that connect is being used here as follows,
connect takes two functions as arguments which are mapStateToProps and mapDispatchToProps.
Now let’s see what these two functions do,
mapStateToProps function as the name suggests maps the redux state to the props of the component it is declared in. So this basically adds whatever state you return from this function to your component. In our counter example, I have returned count from the redux state and hence now I can access count from props inside my component.
mapDispatchToProps function does a very similar thing, but instead of adding state to props, it adds our actions to props! Whatever actions we return from this function are added to our component. And as you can see that in our example I have returned two actions i.e increaseCounter and decreaseCounter, hence we are able to access them from our props and then I release our actions on the respective button click.
Well, now we have a fully functional redux app. If we click on “+” it will increase a number and “-” will decrease a number.
I hope this article was helpful for you to understand Redux. We will be diving in depth on Redux in another article, like how we can reduce all these boilerplates by using Redux-Toolkit and others. But for now, I think that will be it, I hope this article added some value. adios!