Introduction to Redux


It is a predictable state management library for JavaScript applications, commonly used with React. It helps manage and centralize application state, making state changes predictable and easier to debug.
Redux = Context API + useReducer
Why Use Redux?
Centralized State → Stores global state in a single place (Redux store) Predictability → State changes follow strict rules, making debugging easier Easier Debugging → Tools like Redux DevTools help track state changes Better State Management → Useful in large applications with complex state interactions
Core Concepts of Redux
Store A centralized place to hold the application's state.
Actions Plain JavaScript objects that describe what should change in the state.
Reducers Pure functions that specify how the state changes based on actions.
Dispatch Sends actions to update the store.
Selectors Functions that extract and format data from the store.
- Store
It completely stores all the states in one place and making it easier for all the components to access any state
store.js
import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './cartSlice';
const store = configureStore({
reducer: {
cart: cartReducer,
},
});
export default store;
- Action It is a plain JavaScript object that describes what should happen in the application. Actions are sent to the reducer to update the state.
const addItem = (item) => ({
type: 'ADD_ITEM',
payload: item,
});
- Reducer
It is a function that determines changes to an application’s state. It uses the current state and an action to compute and return a new state.
It can be said like Change handler similar to Event Handler
It uses initial state and actions available to create a new state
- Slice
This is used to organize all the reducers for each webpage as a separate entity
We can add initial states and reducers along with api calls
import { createSlice } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: {
cartProductIds: [],
},
reducers: {
addToCart: (state, action) => {
state.cartProductIds = [action.payload, ...state.cartProductIds];
},
removeFromCart: (state, action) => {
const indexOfId = state.cartProductIds.indexOf(action.payload);
if (indexOfId !== -1) {
state.cartProductIds.splice(indexOfId, 1);
}
},
clearAllItems: (state) => {
state.cartProductIds = [];
},
},
});
export const { addToCart, removeFromCart, clearAllItems } = cartSlice.actions;
export default cartSlice.reducer;
- Provider
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './app/store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Hooks required for redux
1) useSelector
This is used to extract particular state from redux store
const selectedData = useSelector((state) => state.someData);
2) useDispatch
This is used to send off actions to the redux store
// src/features/cart/CartComponent.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addToCart, removeFromCart, clearAllItems } from './cartSlice';
const CartComponent = () => {
const cartProductIds = useSelector((state) => state.cart.cartProductIds);
const dispatch = useDispatch();
return (
<div>
<h1>Cart</h1>
<ul>
{cartProductIds.map((id) => (
<li key={id}>
Product ID: {id}
<button onClick={() => dispatch(removeFromCart(id))}>Remove</button>
</li>
))}
</ul>
<button onClick={() => dispatch(clearAllItems())}>Clear All</button>
<button onClick={() => dispatch(addToCart(123))}>Add Product 123</button>
</div>
);
};
export default CartComponent;
Redux Thunk
It is a middleware that allows you to write asynchronous logic (like API calls) inside Redux actions. It enables action creators to return functions instead of plain objects.
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
// Define an async thunk to fetch data
export const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId) => {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
return response.json();
}
);
const userSlice = createSlice({
name: 'user',
initialState: { data: null, loading: false, error: null },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = true;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchUser.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
}
});
export default userSlice.reducer;
Redux Toolkit (RTK)
It is the official, recommended way to write Redux logic. It simplifies state management by reducing boilerplate code, improving performance, and making Redux easier to use.
Stay Connected! If you enjoyed this post, don’t forget to follow me on social media for more updates and insights:
Twitter: madhavganesan
Instagram: madhavganesan
LinkedIn: madhavganesan
Subscribe to my newsletter
Read articles from Madhav Ganesan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Madhav Ganesan
Madhav Ganesan
I am a computer science student passionate about web development and any other technologies that amazes me