Complete Guide to Mastering Redux Toolkit (RTK)
Redux Toolkit (RTK) is the official, recommended way to write Redux logic. It helps eliminate boilerplate, improves readability, and offers powerful tools for scalable state management.
📦 Why Redux Toolkit?
RTK simplifies:
Store configuration
Reducer logic via
createSliceAsync calls via
createAsyncThunkMiddleware setup
Code organization
🔧 Step-by-Step Implementation
1️⃣ Install Redux Toolkit
npm install @reduxjs/toolkit react-redux
2️⃣ Create the Slice (features/counter/counterSlice.ts)
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface CounterState {
value: number;
}
const initialState: CounterState = { value: 0 };
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => { state.value += 1 },
decrement: (state) => { state.value -= 1 },
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
3️⃣ Configure the Store (app/store.ts)
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
4️⃣ Provide the Store (main.tsx)
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<Provider store={store}>
<App />
</Provider>
);
5️⃣ Use Redux in Components (App.tsx)
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from './app/store';
import { increment, decrement } from './features/counter/counterSlice';
function App() {
const count = useSelector((state: RootState) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
}
export default App;
✅ Do’s and ❌ Don’ts
✅ Do’s
Use
createSliceandconfigureStoreNormalize your state if complex
Keep slices modular and scoped
Use
createAsyncThunkfor side-effects
❌ Don’ts
Don’t mutate the state manually outside
createSliceDon’t use legacy Redux boilerplate
Don’t store non-serializable data in Redux state
✅ Pros & ❌ Cons of RTK
| Pros ✅ | Cons ❌ |
| Reduces boilerplate | Learning curve if new to Redux |
| Built-in support for async logic | Some magic under the hood |
| DevTools support out of the box | Might be overkill for small apps |
| Encourages best practices | Slight abstraction from Redux core |
🔁 Code Flow Diagram
Here's a visual representation of the Redux Toolkit flow in an app:
📌 Summary
Redux Toolkit brings the best of Redux while reducing its complexity. Mastering RTK means embracing best practices and writing scalable, clean code.