Redux can be confusing for beginner React developers. There are various concepts you should know to utilize appropriately, like actions, reducers, store, immutability, pure form methods, and much more. Each React developer ought to know the essentials of how to work with Redux since various industry projects regularly utilize it to oversee bigger projects. In this article, we’ll explore the essentials of Redux and how to use it.
Redux is a library for state management that helps you manage the state in your applications in a better way. The Redux library isn’t particular to React. It’s a library that you can utilize in any other library or systems like Angular, VueJS, and even vanilla JavaScript. But, designers generally utilize Redux when working with React. Redux gives a single store that you can use to oversee a huge amount of information and data.
To learn about the basics of Redux, let’s create a new React app. To do so, execute the following command in a terminal/Powershell/command prompt.
npx create-react-app redux
npx command allows us to use the create-react-app package of node package manager (npm) to create a new React app without installing it on our local machine. It will create a new React app with the name of redux. Now that we’ve created a project, the next step is to erase all existing files in the src folder, and create a new file with the name index.js in it. Now, install the Redux library from the npm. For this, open the terminal window again in the redux directory and execute the following command.
npm install redux@4.1.0
In Redux, we use the store to track and manage the data that is changing in our app. For this to be done we have to create a Redux store by importing the createStore method from redux as given below-
import { createStore } from 'redux';
The createStore method accepts three parameters:
The first parameter is a method that’s ordinarily known as a reducer.
The second parameter is the starting value of the state.
The third parameter is an enhancer where we can pass middleware, if any.
The first parameter, reducer, is the only required parameter. The other two are optional.
1
2
3
4
5
6
7
8
import {
createStore
} from 'redux';
const reducer = (state, action) => {
return state;
};
const store = createStore(reducer, 0);
In the reducer method, we are returning the value of state and then we pass the reducer method as a required parameter of the createStore function, and here the second argument represents the initial value of the state. The reducer method accepts action and state as the arguments and createStore function returns store which we use to track and manage the changing data of our application. But there is another common way to initialize the value of state in the reducer method itself, shown below.
1
2
3
4
5
6
7
8
9
import {
createStore
} from 'redux';
const reducer = (initial_state = 0, action) => {
return initial_state;
};
const store = createStore(reducer);
Now, after creating the Redux store, we use its subscribe method to subscribe and observe the changes in the store.
1
2
3
store.subscribe(() => {
console.log('current state', store.getState());
});
By using the subscribe method we subscribed to a callback method that will be invoked every time data in the Redux store is changed. Inside of that method we are invoking the getState method of the store to get the current value of the state (after data is changed, i.e., a new state). Add the following code in the index.js file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import {
createStore
} from 'redux';
const reducer = (initial_state = 0, action) => {
console.log('reducer method invoked.');
return initial_state;
};
const store = createStore(reducer);
store.subscribe(() => {
console.log('current state', store.getState());
});
If you follow the process carefully you will see the “reducer method invoked.” message on the console after running the development server by executing the command npm start in the terminal and opening http://localhost:3000/ in the browser.
We are done creating the store, though it won’t be utilized by us much right now. This is because the store is associated with utilizing the reducer method, but we have not included any instruction inside the reducer function to oversee the store. To change the data in the Redux store we have to dispatch the actions. To do so we send action as an object to the store, as shown below.
1 2 3
store.dispatch({ type: 'INCREASE' })
In the above code, we are calling the inbuilt function dispatch of the Redux store to send an action with the type attribute “INCREASE”. Type can be anything according to what you need for your action call. You can give a meaningful name to the type attribute, it’s standard practice to name the type in UPPERCASE. Now we have to define the actions we used for transforming the data in the store.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import {
createStore
} from 'redux';
const reducer = (initial_state = 0, action) => {
if (action.type === 'INCREASE') {
return initial_state + 1;
} else if (action.type === 'DECREASE') {
return initial_state - 1;
}
return initial_state;
};
const store = createStore(reducer);
store.subscribe(() => {
console.log('current state : ', store.getState());
});
const actions = ['INCREASE', 'DECREASE', 'INCREASE'];
actions.forEach((action_type) => {
store.dispatch({
type: action_type
});
})
If you restart the development server by the npm start command and open http://localhost:3000/, the following messages should be printed on the console.
We dispatched three actions and as the store is changed thrice, we get three logs printed on the console as per the type of action we sent to the store. There is one more attribute of action, payload, where you can send the extra data as part of an action.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import {
createStore
} from 'redux';
const reducer = (initial_state = 0, action) => {
if (action.type === 'INCREASE') {
return initial_state + action.payload;
} else if (action.type === 'DECREASE') {
return initial_state - action.payload;
}
return initial_state;
};
const store = createStore(reducer);
store.subscribe(() => {
console.log('current state : ', store.getState());
});
const actions = [
{
type: 'INCREASE',
payload: 10
}, // to increase by 10
{
type: 'DECREASE',
payload: 5
}, // to decrease by 5
{
type: 'INCREASE',
payload: 30
}, // to increase by 30
]
actions.forEach((action) => {
store.dispatch(action);
})
Now if you restart the development server you will see these logs printed on the console.