# How to Manage Global State in Next.js Using Redux Toolkit

Managing global state in a Next.js application can be tricky, but Redux Toolkit (RTK) makes it easier by reducing boilerplate and improving performance. In this guide, we’ll walk through integrating Redux Toolkit with Next.js to efficiently manage application state.

---

## Why Use Redux Toolkit in Next.js?

Next.js is a powerful React framework with built-in features like SSR (Server-Side Rendering) and SSG (Static Site Generation). However, it doesn’t provide a built-in solution for global state management. That’s where Redux Toolkit comes in.

### Benefits of Redux Toolkit:

* **Less Boilerplate**: Simplifies state management with built-in utilities.
    
* **Efficient Performance**: Uses Immer for immutable updates and Redux Thunk for async actions.
    
* **Better Developer Experience**: Includes built-in middleware and debugging tools.
    

---

## Setting Up Redux Toolkit in Next.js

### Step 1: Install Dependencies

Run the following command in your Next.js project:

```typescript
npm install @reduxjs/toolkit react-redux
```

### Step 2: Create a Redux Store

Inside your project, create a folder `store` and add a file called `store.ts`:

```typescript
// store/store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slices/counterSlice';

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

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
```

### Step 3: Create a Slice

Inside the `store` folder, create a `slices` directory and add `counterSlice.ts`:

```typescript
// store/slices/counterSlice.ts
import { createSlice } from '@reduxjs/toolkit';

const initialState = { value: 0 };

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

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
```

### Step 4: Provide the Store to Next.js

Next.js doesn’t have a built-in provider for Redux, so we wrap our app with the Redux Provider.

Modify `pages/_app.tsx`:

```typescript
// pages/_app.tsx
import { Provider } from 'react-redux';
import { store } from '../store/store';
import type { AppProps } from 'next/app';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  );
}

export default MyApp;
```

### Step 5: Use Redux State in Components

Now, let’s use Redux state in a component.

Create `components/Counter.tsx`:

```typescript
// components/Counter.tsx
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../store/store';
import { increment, decrement } from '../store/slices/counterSlice';

export default function Counter() {
  const count = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}
```

### Step 6: Add Counter to a Page

Modify `pages/index.tsx`:

```typescript
// pages/index.tsx
import Counter from '../components/Counter';

export default function Home() {
  return (
    <div>
      <h1>Welcome to Redux Toolkit in Next.js</h1>
      <Counter />
    </div>
  );
}
```

---

## Using Redux Toolkit with the Next.js App Router

If you’re using the **App Router (app directory)** in Next.js, the setup is slightly different. Instead of wrapping `_app.tsx`, you’ll use a provider in `layout.tsx`.

### Step 1: Modify `store.ts` (Same as Above)

### Step 2: Provide Store in `layout.tsx`

Modify `app/layout.tsx`:

```typescript
// app/layout.tsx
import { Provider } from 'react-redux';
import { store } from '../store/store';
import type { ReactNode } from 'react';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Provider store={store}>{children}</Provider>
      </body>
    </html>
  );
}
```

Use `‘use client’`, if **This function is not supported in React Server Components. Please only use this export in a Client Component.**

### Step 3: Use Redux in a Server Component

In the App Router, Redux is primarily used in Client Components. Mark components as **'use client'** at the top.

Modify `app/components/Counter.tsx`:

```typescript
// app/components/Counter.tsx
'use client';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../store/store';
import { increment, decrement } from '../store/slices/counterSlice';

export default function Counter() {
  const count = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}
```

### Step 4: Add Counter to a Page

Modify `app/page.tsx`:

```typescript
// app/page.tsx
import Counter from './components/Counter';

export default function Home() {
  return (
    <div>
      <h1>Welcome to Redux Toolkit in Next.js (App Router)</h1>
      <Counter />
    </div>
  );
}
```

---

## Conclusion

Redux Toolkit makes state management in Next.js simple and efficient. Whether you use the **Pages Router or the App Router**, the integration process is straightforward.

### Next Steps:

* Explore **Redux Persist** to save state between page reloads.
    
* Use **RTK Query** for fetching and caching data.
    
* Implement **middleware** for advanced state management.
