Redux is the most usable library for state management in React Js. It makes our application very simplified for maintaining the state. You can access the application state in any of your components. No matter what hierarchy has that component. In this post, I will explain React Redux. For demonstrating it properly, I will create a basic demo of the counter app. In our previous post, we already did the React setup. Also, we saw the Redux Setup in React app. I have already done the setup of the project in the previous post. Please do the setup for the project.
When working with React Redux you need to understand 3 things
- Actions: Actions are the objects that should have the two properties. One describes the type of actions and the second describes what should be changed in the state.
- Reducers: These are the pure functions that take the actions and the previous state of the app. Reducers job is to return the new state to the application.
- Store: It simply manages the state of the application. It brings the actions and reducers together. It holds and changes the state of the whole application. There will be only one store for the entire application.
Redux is made up of Actions, Reducers, State, and Store. Each thing does a specific task.
Form Handling in React JS Using React Hook Form Library
How React Redux Works
Let’s say we have a react component that increments the value by 1 on each button click. When we will click a button, it will call an event handler function. Shown in the below diagram.
This is where we dispatch an action. Dispatch is a function given by redux. So when an event handler function is called, it dispatches an action. The action contains a type and payload.
- The type is nothing but the name of the action. In this case, it will be INCREMENT.
- The payload contains the data, that we need to know about. In this case, we increment the value by 1. So the payload is 1 (You can keep payload values 2, 3, 4… etc according to your need). It is shown in the below diagram.
Then this action will be passed to the store.
How Store and Reducer Works in React Redux
The store receives the action. The store is just like a database that manages the data and updates the state. In other words, it is the coordinator of updating the state based on the action.
Using the reducer function the current state and the action will get passed. A reducer takes the current state and action from the store. It combines things together and does some work in the reducer and returns a new state. Take a look at the below diagram.
The store then saves the new state which is returned from the reducer. In this case, we got 1 and pass the new state to the component. Which causes them to re-render to display the new data. Shown in the below diagram.
Now let’s understand the entire flow by an example of the counter.
Create a Demo For Counter
We will create a simple design like this.
It will require creating a couple of files.
- Create a component with the name Counter.js in the components folder.
- Now, create another folder named redux. Inside this folder, create three different folder like this-
src
|__ components
| |__ Counter.js
|
|__ redux
| |__ actions
| | |__ actionTypes.js
| | |
| | |__ index.js
| |
| |__ reducers
| | |__ counterReducer.js
| | |
| | |__ index.js
| |
| |__ store
| |__ index.js
You can see the structure in the below screenshot as well.
Add Functionality of Counter
Now, start with the Counter.js component. Add the below snippet.
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement } from '../redux/actions';
export const Counter = () => {
const counter = useSelector((state) => state.counterReducer.count);
const dispatch = useDispatch();
const handleIncrement = () => {
dispatch(increment(1));
};
const handleDecrement = () => {
dispatch(decrement(1));
};
return (
<div>
<h1>Counter {counter} </h1>
<button className='btnStyle' onClick={()=>handleIncrement()}>+</button>
<button className='btnStyle' onClick={()=>handleDecrement()}>-</button>
</div>
);
};
Add Action and Reducer For Counter
In the next step, go to the actionTypes.js and add the below code.
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
After that import the actions in its index.js file. Here, you have to set the payload as shown below.
import { INCREMENT, DECREMENT } from './actionTypes';
export const increment = (number) => {
return {
type: INCREMENT,
payload: number
};
};
export const decrement = (number) => {
return {
type: DECREMENT,
payload: number
};
};
Next, navigate to the counterReducer.js and add the below code. The reducer will return the state based on the action type.
const initialState = {
count: 0,
};
export const counterReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + action.payload
};
}
switch (action.type) {
case 'DECREMENT':
return {
...state,
count: state.count - action.payload
};
default:
return state;
}
};
Reducer needs to register in its index file. Hence, navigate to the reducers/index.js file and add the below code.
import { combineReducers } from 'redux';
import counterReducer from './counterReducer';
export default combineReducers({
counterReducer,
})
Next, add the below code in store/index.js. Here, it will create the redux store.
import { createStore } from "redux";
import rootReducer from "../reducers";
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;
That’s it for the redux setup. Now, come to the default index.js file. We will import this redux store there.
Render Main Component
The redux store will need to import in the root of the react component. So, by default, we have the index.js for this. Hence, add the below code.
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import { App } from "./App";
import store from "./redux/store";
import { Provider } from "react-redux";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
Lastly, come to the App.js component and render the Counter.js component here.
import "./App.css";
import React from "react";
import { Counter } from "./components/Counter";
export const App = () => {
return (
<div className="app">
<Counter />
</div>
);
};
I have added basic CSS for buttons and backgrounds. So, it is optional.
.app {
text-align: center;
margin: 5% 20%;
background-color: #f2aa4cff;
color: black;
height: 200px;
padding-top: 2%;
border-radius: 10px;
}
.btnStyle {
background-color: #a9a9a9;
color: black;
width: 20%;
font-size: 35px;
margin-right: 20px;
border: none;
border-radius: 7px;
}
Result of Counter App
Run the application and check the result. When you will click on the increment button, the value will be incremented by 1 and the response will return from the state. Similarly, on decrementing, it will decrement by 1. In this activity, the data is coming from the redux in realtime.
Bottom Lines
That’s it for this post on React Redux. Here, we have seen the step-by-step flow of the Redux operations. We understood how the event handler dispatches the action to the reducer. The reducer returns the state based on the action type. I hope this will help you to get a basic idea of React Redux concept. In the upcoming post, we will work on some complex apps. Thank you.
Leave a Reply