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 createSlice

  • Async calls via createAsyncThunk

  • Middleware 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 createSlice and configureStore

  • Normalize your state if complex

  • Keep slices modular and scoped

  • Use createAsyncThunk for side-effects

❌ Don’ts

  • Don’t mutate the state manually outside createSlice

  • Don’t use legacy Redux boilerplate

  • Don’t store non-serializable data in Redux state


✅ Pros & ❌ Cons of RTK

Pros ✅Cons ❌
Reduces boilerplateLearning curve if new to Redux
Built-in support for async logicSome magic under the hood
DevTools support out of the boxMight be overkill for small apps
Encourages best practicesSlight abstraction from Redux core

🔁 Code Flow Diagram

Here's a visual representation of the Redux Toolkit flow in an app:

Generated image


📌 Summary

Redux Toolkit brings the best of Redux while reducing its complexity. Mastering RTK means embracing best practices and writing scalable, clean code.

0
Subscribe to my newsletter

Read articles from Chitta Ranjan Mohapatra directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chitta Ranjan Mohapatra
Chitta Ranjan Mohapatra