Components follow the tree structure and hence the states needed for each component needs to be passed as the props. This is not a big issue in case of a basic react application. But when things go high, passing states as props will not be a good option. Redux is the solution to this problem.
Note: It doesn’t need to use Redux inside a React app with fewer components and states. This makes our project more complicated.
In React, we can only work with Components and states. We have to pass the needed states to each component as props. But when we are using Redux inside React, it’s easier. There are not states for each component rather than a universal Store. The workflow of Redux is shown below.
Here components can create actions. Actions are nothing but an object containing the “Type” and “Payload”. Type is a unique name which helps to switch the action later and Payload contains the state values to states.
This action is dispatched to Reducers and from reducer, the actions are triggered according to corresponding “Type”. Now, the values from the components are stored in the “Store” by “Reducer”. Reducer is the part which is accessible by Store.
When the value of states in the store is changed, it gets reflected in the components also.
Ok! that’s all about Redux. Now I am entering to the topic without explaining much about Redux.
COUNTER APP USING REACT AND REDUX
After successful installation of Nodejs and npm, install react using the below command.
npx create-react-app counter-app
If you need further assistance on the installation of React on your system, use the below links.
After successful installation of React, install redux package inside your project.
npm i redux
Now install react-redux, which is the official react binding for redux.
npm i react-redux
This package can show us the logs of our redux project.
npm i redux-logger
The below image shows the full file structure of the project we are going to do.
I am going to explain about the folders in this project.
- actions: It contains files where all the actions are defined.
- components: components directory contains all the stateless components (components which do not have state) in our project.
- containers: It contains the stateful components(components which have the state) in our project.
- reducers: Reducers decide how the state can be updated corresponding to a particular action.
- store: This directory deals with the store creation.
Now let’s have some code…
First, we need to set up our index.js file.
- import all the components.
- I have a CounterComponent inside containers directory. This is wrapped inside Provider (a higher order component by redux)
- The store is also called inside Provider.
Now create a CounterComponent.js file inside ./containers directory.
- import all components. The connect is a component helps to connect mapStateToProps and mapDispatchToProps functions with the component. The incrementCount and decrementCount are actions defined under actions.
- handleBtnActionIncrement and handleBtnActionDecrement are functions which executes with the button clicks. These functions call the corresponding actions. mapStateToProps and mapDispatchToProps will map all states and all the actions to props correspondingly.
Now the button component is also defined in Button.js under ./components directory.
- Button onClick function and title are passed as props from CounterComponent.js to this component.
Now we need to declare an action for corresponding functions of the button clicks.
- INCREMENT_COUNT is the action which triggers by clicking the “+” button. Here the count becomes count + 1.
- DECREMENT_COUNT is the action which triggers by clicking the “-” button. Here the count becomes count – 1.
We need to create and index.js file under ./reducers directory which is used when more than two reducers are present in our project.
Now, we need to create a CounterReducer.js file in the same directory to trigger the action according to the type.
- Here we initialize the default value of count as 0.
- Switching statements set the state according to the action type
At last, we need to create a file named index.js inside ./store directory. This is to store the changed states. Container components read states from here.
The complete project I created is uploaded in GitHub and you can always refer it.
Have a nice code !