DEV Community

Cover image for Using React Context API in Next.js 15 for Global State Management
Saiful Islam
Saiful Islam

Posted on

Using React Context API in Next.js 15 for Global State Management

In modern Next.js applications, state management is essential for maintaining global UI states like modals, sidebars, and theme toggles. While Redux and Zustand are powerful options, React Context API is a lightweight and built-in solution for simpler global states.

In this guide, we’ll build a global state manager in Next.js 15 using Context API and TypeScript, with a custom hook for seamless usage.


Step 1: Create a Context for Global State

We start by creating a StateContext to manage a simple open state (e.g., for a modal or sidebar):

πŸ“Œ StateContext.tsx

"use client";
import { createContext, useCallback, useMemo, useState } from "react";

interface StateContextProps {
  open: boolean;
  handleSetOpen: VoidFunction;
}

const StateContext = createContext<StateContextProps | null>(null);

const StateContextProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const [open, setOpen] = useState<boolean>(false);

  const handleSetOpen = useCallback(() => setOpen((prev) => !prev), []);

  const contextValue = useMemo<StateContextProps>(
    () => ({ open, handleSetOpen }),
    [open, handleSetOpen]
  );

  return (
    <StateContext.Provider value={contextValue}>
      {children}
    </StateContext.Provider>
  );
};

export { StateContextProvider, StateContext };
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Why This Works:
βœ… Uses useCallback to optimize state updates.
βœ… Uses useMemo to prevent unnecessary re-renders.
βœ… Provides open and handleSetOpen globally.


Step 2: Create a Custom Hook for Accessing Context

Instead of using useContext(StateContext) every time, we create a custom hook to simplify access.

πŸ“Œ useStateData.tsx

"use client";
import { StateContext } from "@/contexts/StateContext";
import { useContext } from "react";

export default function useStateData() {
  const context = useContext(StateContext);
  if (!context) {
    throw new Error("useStateData must be used within a StateContextProvider");
  }
  return context;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Why This is Useful:
βœ… Encapsulates useContext to avoid repetitive code.
βœ… Throws an error if used outside StateContextProvider.


Step 3: Implement Context in a Next.js 15 Application

Now, let’s use the context in a Next.js 15 component.

πŸ“Œ layout.tsx

import { StateContextProvider } from "@/contexts/StateContext";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <StateContextProvider>{children}</StateContextProvider>
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

βœ… Ensures the context is available throughout the app.


Use the Context in a Component

πŸ“Œ ToggleButton.tsx

"use client";
import useStateData from "@/hooks/useStateData";

export default function ToggleButton() {
  const { open, handleSetOpen } = useStateData();

  return (
    <button
      onClick={handleSetOpen}
      className="px-4 py-2 bg-blue-600 text-white rounded-md"
    >
      {open ? "Close Sidebar" : "Open Sidebar"}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

πŸ“Œ Sidebar.tsx

"use client";
import useStateData from "@/hooks/useStateData";

export default function Sidebar() {
  const { open } = useStateData();

  return (
    <aside
      className={`fixed top-0 left-0 h-full w-64 bg-gray-900 text-white transform ${
        open ? "translate-x-0" : "-translate-x-full"
      } transition-transform`}
    >
      <p className="p-4">Sidebar Content</p>
    </aside>
  );
}
Enter fullscreen mode Exit fullscreen mode

Final Integration in a Page

πŸ“Œ page.tsx

import ToggleButton from "@/components/ToggleButton";
import Sidebar from "@/components/Sidebar";

export default function HomePage() {
  return (
    <main className="flex flex-col items-center justify-center min-h-screen">
      <ToggleButton />
      <Sidebar />
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

βœ… Now, clicking the button toggles the sidebar state globally!


Final Thoughts

πŸš€ Why Use Context API for Global UI State?
βœ… Built into React – No need for external state libraries.
βœ… Works perfectly in Next.js 15.
βœ… Great for UI state like modals, sidebars, and themes.

Top comments (0)