DEV Community

Dev Cookies
Dev Cookies

Posted on

πŸš€ One-Stop Guide to Building a Scalable React App Using Redux Toolkit (with Code)

🧠 Why Redux Toolkit?

If you've ever worked with plain Redux, you know it can be... a lot. Redux Toolkit (RTK) is the official, modern way to write Redux logicβ€”boilerplate-free, scalable, and fun!


🎯 What We'll Build

A simple app that:

  • Manages a counter
  • Tracks user login state
  • Uses multiple slices
  • Follows best practices for scalability

This can be your starter template for any scalable app.


πŸ“¦ Step 1: Install the Dependencies

npm install @reduxjs/toolkit react-redux
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add @reduxjs/toolkit react-redux
Enter fullscreen mode Exit fullscreen mode

🧩 Step 2: Create Redux Slices

πŸ”’ counterSlice.js

// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1; },
    decrement: state => { state.value -= 1; },
    reset: state => { state.value = 0; }
  }
});

export const { increment, decrement, reset } = counterSlice.actions;
export default counterSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

πŸ™ userSlice.js

// src/features/user/userSlice.js
import { createSlice } from '@reduxjs/toolkit';

const userSlice = createSlice({
  name: 'user',
  initialState: { name: '', loggedIn: false },
  reducers: {
    login: (state, action) => {
      state.name = action.payload;
      state.loggedIn = true;
    },
    logout: state => {
      state.name = '';
      state.loggedIn = false;
    }
  }
});

export const { login, logout } = userSlice.actions;
export default userSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

πŸ—οΈ Step 3: Configure Store

// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
import userReducer from '../features/user/userSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer,
    user: userReducer,
  },
});

export default store;
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ Step 4: Wrap App with Provider

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './app/store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Step 5: Build Components Using Redux Logic

// src/components/Dashboard.jsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, reset } from '../features/counter/counterSlice';
import { login, logout } from '../features/user/userSlice';

function Dashboard() {
  const dispatch = useDispatch();
  const counter = useSelector(state => state.counter.value);
  const user = useSelector(state => state.user);

  return (
    <div style={{ padding: 20 }}>
      <h1>πŸ”₯ Redux Toolkit App</h1>
      <h2>Counter: {counter}</h2>
      <button onClick={() => dispatch(increment())}>+ Increment</button>
      <button onClick={() => dispatch(decrement())}>- Decrement</button>
      <button onClick={() => dispatch(reset())}>Reset</button>

      <hr />

      {user.loggedIn ? (
        <>
          <h2>Welcome, {user.name}!</h2>
          <button onClick={() => dispatch(logout())}>Logout</button>
        </>
      ) : (
        <>
          <h2>Please log in</h2>
          <button onClick={() => dispatch(login('John Doe'))}>Login as John</button>
        </>
      )}
    </div>
  );
}

export default Dashboard;
Enter fullscreen mode Exit fullscreen mode

🧩 Add More Functionality (Optional)

βœ… Theme Slice

// src/features/theme/themeSlice.js
import { createSlice } from '@reduxjs/toolkit';

const themeSlice = createSlice({
  name: 'theme',
  initialState: { darkMode: false },
  reducers: {
    toggleTheme: state => {
      state.darkMode = !state.darkMode;
    }
  }
});

export const { toggleTheme } = themeSlice.actions;
export default themeSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

And in store.js:

import themeReducer from '../features/theme/themeSlice';

...

reducer: {
  counter: counterReducer,
  user: userReducer,
  theme: themeReducer
}
Enter fullscreen mode Exit fullscreen mode

Use it in your component just like the others!


βœ… Folder Structure Suggestion

src/
β”‚
β”œβ”€β”€ app/
β”‚   └── store.js
β”œβ”€β”€ features/
β”‚   β”œβ”€β”€ counter/
β”‚   β”‚   └── counterSlice.js
β”‚   β”œβ”€β”€ user/
β”‚   β”‚   └── userSlice.js
β”‚   └── theme/
β”‚       └── themeSlice.js
β”œβ”€β”€ components/
β”‚   └── Dashboard.jsx
└── App.jsx
Enter fullscreen mode Exit fullscreen mode

🧠 Tips for Production-Ready Apps

  • Use createAsyncThunk for async API calls
  • Use RTK Query for advanced API integration (built-in!)
  • Persist Redux state with redux-persist
  • Use TypeScript for type safety in large apps

🏁 Final Thoughts

Redux Toolkit makes managing app state easy, powerful, and less verbose. The combination of slices and the configureStore abstraction provides a clean way to build scalable apps.

Top comments (0)