STATE MANAGEMENT : REDUX

Nurşin Keleş
4 min readJun 15, 2022

Most people are always focused on where the industry is heading, what the latest techs are and the latest frameworks that are available. I gotta say, Redux is one of the most popular state management tools. However, it is also known to be difficult to get learned with. Even if you’re just getting started, I have no doubt that you can learn if you practice and don’t give up.

Why Do We Need Redux ?

Developers have used Redux in order to avoid prop drilling.

Prop Drilling: Prop drilling is the process in a React app where props are passed from one part of a tree to another by going through other parts that do not need the data, but only help in passing it through the tree.

Another factor to consider is, Redux should only be used if the value is needed by many components at different nesting levels. It can reduce the re-usability of your component, and so don’t use it for every property — only ones that are “global” to your application.

Main Elements of Redux

Data transfer in redux takes place through 3 basic elements.

Action: Actions are a plain JavaScript object that contains information. Actions are the only source of information for the store. Actions have a type field that tells what kind of action to perform and all other fields contain information or data.

Reducer: Reducers determine how the state of the application will be changed as a result of the action coming to the store. Actions, on the other hand, only tell the application what will happen, they do not know how to change the state of the application.

Store: In simple terms, It is the area where the data you will create with the Redux library is kept.

Redux Data Flow

Example: Counter App

Let’s go through a simple counter application example in order to better understand Redux.

First and above all, We install the redux toolkit in our project.

index.js

We wrap our application with provider to use our store in components. We give the store as the parameter.

import React from "react";
import ReactDOM from "react-dom";
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")
);

store.js

As stated above, Store is an object that holds the values of the elements in our global state.

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counter/counterSlice";
export const store = configureStore({ reducer: {
counter: counterReducer,
},
});

counterSlice.js

I am building the structure consisting of name, initial State, reducers using counter slice.

import { createSlice } from "@reduxjs/toolkit";export const counterSlice = createSlice({  name: "counter",
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += Number(action.payload);
},
},
});export const { increment, decrement, incrementByAmount } = counterSlice.actions;export default counterSlice.reducer;

When any change is made, we define it in the reducers section. Such as incrementByAmount, If the parameter is sent, the action is added.

We export the definitions we wrote in Reducers to be dispatched. For this reason, we can import and use it in related components.

Now let’s come to the component part.

Counter.js

As you can see in the code block below, we used the useSelector and useDispatch hooks in this example. We are using callback in the useSelector hook. We used the value in the initial state found in the global state. We used useDispatch hook to change the value of value. We need to dispatch the action using the useDispatch hook so that this change is provided in the reducer and written to the store. In addition, we dispatch it in the onClick event.

import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import {increment, decrement, incrementByAmount} from "../redux/counter/counterSlice";
function Counter() { const [amount, setAmount] = useState(3);
const countValue = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<>
<h1>{countValue}</h1> <button onClick={() => dispatch(decrement())}>Decrement</button> <button onClick={() => dispatch(increment())}>Increment</button> <input type="number" value={amount}
onChange={(e) => setAmount(e.target.value)} />
<button onClick={() => dispatch(incrementByAmount(amount))}>
Increment by Amount
</button>
</>
);
}export default Counter;

The project source code is available at

Github: https://github.com/nursinkeles/reduxTutorials/tree/main/counter-app

I recommend you to review the redux toolkit documentation for convenience.

Another necessary factor is the Redux DevTools Extension. You can install the Redux DevTools Extension in your development environment (Google Chrome) to visualize actions and state changes that take place in a redux application.

Conclusion

As you know the pros and cons of Redux, which has a large community, are quite a lot. Taking everything into consideration, Redux is a useful way to improve the readability of your code and avoid prop drilling. From my point of view, you write too much code even though you can do the same job without using redux. For this reason, instead of using it in every project, you should use it when needed.

In the light of this information, I hope this article was helpful :)

--

--