Introduction
Redux is a global state manager that allows you to manage your app state in a single place, which can be very useful. Redux has long been a cornerstone for state management in React applications, but it’s no secret that the original Redux setup was often too verbose and hard to learn. Developers had to write a lot of boilerplate just to do simple things like updating a counter or fetching data from an API.
Then came Redux Toolkit (RTK) — the official, recommended way to write Redux code.
RTK simplifies Redux development by providing powerful utilities that make state management easier, faster, and less error-prone.
In this guide, we’ll explore what Redux Toolkit is, why it matters, and how to use it effectively — with practical examples you can drop straight into your next React project.
What is Redux Toolkit?
Redux Toolkit (RTK) is the official, opinionated, batteries-included toolset for efficient Redux development.
It was created by the Redux team to solve the biggest issues developers had with Redux: excessive boilerplate, complex store configuration, and too many added packages.
RTK provides:
- A simplified store configuration.
- Built-in reducers and immutable updates using Immer.
- Easy action creation.
- Integrated middleware for async logic (like redux-thunk).
- DevTools support and production-ready defaults out of the box.
In a nutshell, Redux Toolkit is an easier and modern way to implement the power of Redux as a global state manager. RTK lets you write less code, avoid common bugs, and get better performance — all while keeping the predictability of Redux.
Redux Toolkit itself is a single package, @reduxjs/toolkit
. However, it is designed to be "batteries-included"; consequently, when you install it, you install the following integrated libraries:
- Redux core: Redux Toolkit builds on top of the core Redux library, so it's a fundamental part of the toolkit.
- Immer: This library simplifies immutable state updates, which is crucial for Redux. Redux Toolkit leverages Immer internally, particularly with
createSlice
. - Redux Thunk: This middleware enables handling asynchronous actions in Redux, and it's included by default in Redux Toolkit's configureStore.
- Reselect: This library helps create memoized selectors for optimizing state access, and it's often used alongside Redux Toolkit.
- Redux DevTools Extension: While a separate browser extension, Redux Toolkit's configureStore integrates with it by default for enhanced debugging.
In essence, when you install RTK, you are installing one package, but you are gaining access to a comprehensive set of tools and best practices, including the functionalities provided by these integrated libraries.
Although RTK is framework agnostic in this article, we will look at how to use RTK and React.
The prerequisites for this article are listed below:
Prerequisites
- NodeJS should be installed on your system
- Knowledge of React
- Knowledge of JavaScript
- Knowledge of Redux is not required, but it is an added advantage
React and Redux Toolkit
React has revolutionized the way developers build user interfaces. Its component-based architecture, virtual DOM, and declarative syntax make it a powerful library for creating dynamic web applications.
However, as applications grow, managing the state becomes challenging. Passing props through multiple components or handling complex asynchronous data can quickly lead to “prop drilling” and tangled logic. That’s where Redux Toolkit comes in — the modern, opinionated way to manage global state in React applications.
In this article, we create a simple counter application to learn how to set up Redux Toolkit and React.
Installation
We will work with Vite in this article. Vite is a super-fast build tool that replaces Create React App (CRA) for modern React development. To use it, in your terminal, run the code below:
npm create vite@latest counter-app
You’ll be prompted with something like this:
? Select a framework: › - Use arrow-keys. Return to submit.
Vanilla
❯ React
Vue
Svelte
Others
Choose React.
Now go into the app folder by running:
cd counter-app
Then run the app with:
npm run dev
After running the code above, to view the app, visit http://localhost:5173/
, and you will get:
Next, install Redux Toolkit and the react-redux package by running:
npm install @reduxjs/toolkit react-redux
Now we can set up Redux Toolkit inside the app. To do this, first, we configure the Redux store by following the steps in the next section.
Configure the Store
Redux store
and Redux are kind of used interchangeably; both stand for a container for JavaScript apps. And this stores the whole state of the app in an immutable object tree.
To configure the Redux store
, create an app
directory inside the src
directory. Then create a file named store.js
inside the src
directory. Now add the code below to the store.js
file:
// app/store.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
export const store = configureStore({
reducer: { },
});
After configuring the store
, we need to provide the global state to our application.
Provide the store
to React
To provide the store
to React, replace the code in the main.jsx
with the following code:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
import { store } from "./app/store.js";
import { Provider } from "react-redux";
createRoot(document.getElementById("root")).render(
<StrictMode>
<Provider store={store}>
<App />
</Provider>
</StrictMode>
);
In the code above, we used the Provider
component to provide our store
— our global state, to our application. Next, we create a slice.
Create a Slice
The term slice comes from splitting up a Redux state object into multiple slices of state.
A slice contains your state, reducers, and automatically generated actions for a single feature in the app. For example, a blog might have a slice for posts and another slice for comments. So in this article, our app will have a slice for counter
. To create the counter slice, create a folder called features
inside the src
directory, and inside the features
directory, create another directory called counter
, then create a file named counterSlice.js
in the counter
directory and add the code below to the counterSlice.js
:
// features/counter/counterSlice.js
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
reset: (state) => {
state.count = 0;
},
},
});
export const { increment, decrement, reset } = counterSlice.actions;
export default counterSlice.reducer;
In the code above, RTK automatically creates actions with the same name as the reducers provided, and these actions are exported.
Also, RTK uses Immer.js
internally, allowing you to write “mutating” logic safely, as seen in the reducers in the code above.
Update the Store
After creating the counterSlice
, we need to add the counterReducer
to the store
. To do this, update the code in the store.js
file as seen below:
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
Now that we have added the counterReducer
to the store
, it is available to the entire app through the Provider
.
Use the Store in Components
To do this, in the counter
directory inside the features
directory, create a Counter.js
file and add the following code to this file:
// features/counter/Counter.js
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement, reset } from "./counterSlice";
const Counter = () => {
const count = useSelector((state) => state.counter.count);
const dispatch = useDispatch();
const resetAll = () => {
dispatch(reset());
};
return (
<section>
<p>{count}</p>
<div>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
<div>
<button onClick={resetAll}>Reset</button>
</div>
</section>
);
};
export default Counter;
In the code above, the useSelector
and the useDispatch
hooks are imported from react-redux
.
Also, the increment
, decrement
, and reset
action creators are imported from the counterSlice
.
The useSelector
hook is used to get the value of count
from the counterSlice
, while the useDispatch
hook is used to dispatch actions — created by invoking an action creator following the click of a button. So in the code above, actions created by the increment
, decrement
, and reset
action creators are handled by the increment
, decrement
, and reset
reducers in the counterSlice
.
Now, to view the counter
, we replace the codes in the App.js
file with the following:
import Counter from "./features/counter/Counter";
function App() {
return (
<main className="App">
<Counter />
</main>
);
}
export default App;
Then replace the codes in the index.css
file with the following:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
font-size: 5rem;
display: grid;
place-content: center;
}
input,
button {
font: inherit;
padding: 0.5rem;
}
section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
input {
text-align: center;
max-width: 2.5em;
}
button {
font-size: 2rem;
margin: 0.5em 0 0.5em 0.5em;
min-width: 2em;
}
button:first-child {
margin-left: 0;
}
Finally, when you view the app in the browser, you get:
You can test the app by clicking on the increment
, decrement
, and reset
buttons.
Conclusion
Redux Toolkit has completely transformed how developers use Redux.
What was once seen as too complicated is now simple, elegant, and enjoyable.
The above application is a simple application that shows how Redux Toolkit is set up and the overall structure of an application. However, I do hope that by following this application, you will get an understanding of Redux Toolkit and how it is used with React.
If you’re still managing state with plain Redux, now is the time to switch. You’ll write cleaner code, reduce bugs, and enjoy a better development experience.
💼 Hire Me
I'm currently available for freelance or full-time frontend or backend development work.
What I do:
- React, Redux Toolkit, NodeJS, ExpressJS, and TailwindCSS
- Building scalable web applications
- Creating responsive, user-friendly UIs
📧 Email: Leave a messsage
🌐 Portfolio: My portfolio
If you like my work, let’s collaborate!
Top comments (0)