If you've ever felt Redux setup was too verbose or complex, you're not alone. That's exactly why I created a concise, beginner-friendly guide to streamline your Redux Toolkit integration in React projects.
This guide walks through setting up Redux Toolkit in a React project using the Todo example from 👉 rtk-demo GitHub.
Steps for RTK setup
Step | Description |
---|
Install | Install @reduxjs/toolkit and react-redux |
Slice | Create a todoSlice for the todos logic |
Store | Configure the Redux store with the todo reducer |
Provider | Wrap the app with the Provider |
Components | Use useSelector and useDispatch in components |
1. Install Redux Toolkit & React-Redux
npm install @reduxjs/toolkit react-redux
2. Create the Todo Slice
Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated. Once a slice is created, we can export the generated Redux action creators and the reducer function for the whole slice.
// src/redux/todoSlice.js
import { createSlice } from "@reduxjs/toolkit";
const todoSlice = createSlice({
name: "todo",
initialState: [],
reducers: {
addTodo: (state, action) => {
state.push({
id: Date.now(),
text: action.payload,
completed: false,
});
},
updateTodo: (state, action) => {
const { id, newText } = action.payload;
const todo = state.find((todo) => todo.id === id);
if (todo) {
todo.text = newText;
}
},
deleteTodo: (state, action) => {
return state.filter((t) => t.id !== action.payload);
},
},
});
// Export actions and reducer
export const { addTodo, updateTodo, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
3. Configure the Store
// src/redux/store.js
import { configureStore } from "@reduxjs/toolkit";
import todoReducer from "./todoSlice";
export const store = configureStore({
reducer: {
todo: todoReducer,
},
});
4. Provide the Store to React
// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
RTK configuration is done, now you can use it in your features/components.
5. TodoInput Component
// src/components/TodoInput.js
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addTodo } from "../redux/todoSlice";
function TodoInput() {
const [text, setText] = useState("");
const dispatch = useDispatch();
const handleAdd = () => {
if (text.trim()) {
dispatch(addTodo(text));
setText("");
}
};
return (
<div>
<input
value={text}
onChange={e => setText(e.target.value)}
placeholder="Enter todo"
/>
<button onClick={handleAdd}>Add Todo</button>
</div>
);
}
export default TodoInput;
6. TodoList Component
// src/components/TodoList.js
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { updateTodo, deleteTodo } from "../redux/todoSlice";
function TodoList() {
const todos = useSelector(state => state.todo);
const dispatch = useDispatch();
const handleUpdate = (id) => {
const newText = prompt("Update todo text:");
if (newText) {
dispatch(updateTodo({ id, newText }));
}
};
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
<button onClick={() => handleUpdate(todo.id)}>Update</button>
<button onClick={() => dispatch(deleteTodo(todo.id))}>Delete</button>
</li>
))}
</ul>
);
}
export default TodoList;
7. App Component
// src/App.js
import React from "react";
import TodoInput from "./components/TodoInput";
import TodoList from "./components/TodoList";
function App() {
return (
<div>
<h2>Redux Toolkit Todo App</h2>
<TodoInput />
<TodoList />
</div>
);
}
export default App;