State management is one of the biggest challenges in modern React applications. Passing props down through multiple components (known as prop drilling) can quickly become messy. That’s where Redux and its modern upgrade, Redux Toolkit, come into play.
In this article, we’ll explore:
What Redux is and why we need it
The problems Redux Toolkit solves
A complete shopping cart example
How everything connects together
A real-world analogy to make it crystal clear
Redux is a state management library. Think of it as a central brain for your app that holds all important data in one place called the store.
Instead of components managing their own states independently, Redux provides:
A store → the single source of truth.
actions → messages describing what should change.
reducers → pure functions that update the state.
👉 With Redux, data flows in one direction, making your app predictable and easier to debug.
While Redux is powerful, using it the old way meant:
Writing separate action types
Writing action creators
Writing long switch-case reducers
Handling immutability manually
This was too much boilerplate.
👉 Enter Redux Toolkit (RTK):
Combines actions + reducers into one unit with createSlice.
Uses Immer.js under the hood so you can safely write state.items.push() instead of spreading arrays manually.
Provides configureStore for easier setup.
Has utilities like createAsyncThunk for async logic.
In short, RTK = Redux made simple.
When using Redux Toolkit, we follow 5 simple steps:
Create a slice with createSlice → defines state + actions + reducers.
Add slices to the store with configureStore.
Wrap your app in a Provider so components can access the store.
Use useSelector to read state.
Use useDispatch to update state.
Let’s see Redux Toolkit in action with a simple shopping cart.
cartSlice.js)import { createSlice } from "@reduxjs/toolkit";
const cartSlice = createSlice({
name: "cart",
initialState: { items: [] },
reducers: {
addItem: (state, action) => {
state.items.push(action.payload); // safe mutation
},
removeItem: (state) => {
state.items.pop();
},
clearCart: (state) => {
state.items.length = 0;
}
}
});
export const { addItem, removeItem, clearCart } = cartSlice.actions;
export default cartSlice.reducer;
👉 Notice how actions and reducer logic are created automatically.
store.js)import { configureStore } from "@reduxjs/toolkit";
import cartReducer from "./cartSlice";
const store = configureStore({
reducer: {
cart: cartReducer
}
});
export default store;
App.jsx)import { Provider, useDispatch, useSelector } from "react-redux";
import store from "./store";
import { addItem, removeItem, clearCart } from "./cartSlice";
function Cart() {
const items = useSelector((state) => state.cart.items); // read state
const dispatch = useDispatch(); // send actions
return (
<div>
<h2>🛒 Cart: {items.join(", ") || "Empty"}</h2>
<button onClick={() => dispatch(addItem("Burger"))}>Add Burger</button>
<button onClick={() => dispatch(removeItem())}>Remove Last</button>
<button onClick={() => dispatch(clearCart())}>Clear Cart</button>
</div>
);
}
export default function App() {
return (
<Provider store={store}>
<Cart />
</Provider>
);
}
Here’s what happens when a user clicks “Add Burger”:
Dispatch → dispatch(addItem("Burger"))
Action Generated → { type: "cart/addItem", payload: "Burger" }
Reducer Runs → updates the items array.
Store Updates → React automatically re-renders the UI.
Redux: Centralized state management for predictable apps.
Problem: Traditional Redux has too much boilerplate.
Redux Toolkit (RTK): Simplifies Redux with createSlice, configureStore, and auto-generated actions.
Best Practice: Always use Redux Toolkit for new projects — it’s faster, cleaner, and the official recommended way.
👉 In short: Redux = State management, RTK = State management made simple.
⚡ If you’re building a modern React app, Redux Toolkit is the go-to choice. It gives you the power of Redux without the headache of writing too much boilerplate.
0
7
0