DEV Community

loading...
Cover image for Next.js, integrate React Context only in certain pages

Next.js, integrate React Context only in certain pages

enoch ndika
React & Node.js developper | Udemy Instructor
・2 min read

Next.js is one of the most popular and widely used React frameworks.

Using the Context API in Next.js is very simple but there are specific cases where you may need to wrap only certain pages by the provider.

To do this, create a new next project

npx create-next-app my-app
Enter fullscreen mode Exit fullscreen mode

We are going to create a context that will increment and decrement a number.

Create a new folder components and inside create a new file named context.js then paste this code

import { createContext, useContext, useState, useCallback } from "react";

const Context = createContext({});

export const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount((prevState) => prevState + 1);
  }, [count]);

  const decrement = useCallback(() => {
    setCount((prevState) => prevState - 1);
  }, [count]);

  return (
    <Context.Provider value={{ count, increment, decrement }}>
      {children}
    </Context.Provider>
  );
};

export function useCount() {
  return useContext(Context);
}
Enter fullscreen mode Exit fullscreen mode

the custom hook useCount() will allow us to use the values passed to the context provider.

In the _app.js file, add this new component

const Noop = ({ children }) => <>{children}</>;
Enter fullscreen mode Exit fullscreen mode

Then in MyApp component which is exported by default, we will add a prop named provider which will be accessible in all pages and its value will be <Noop/>if no context provider is passed as a value.

Now the _app.js file will be like this

import "../styles/globals.css";

const Noop = ({ children }) => <>{children}</>;

function MyApp({ Component, pageProps }) {
  const ContextProvider = Component.provider || Noop;
  return (
    <ContextProvider>
      <Component {...pageProps} />
    </ContextProvider>
  );
}

export default MyApp;
Enter fullscreen mode Exit fullscreen mode

We will consume the provider in the home page like this

import styles from "../styles/Home.module.css";
import { CountProvider, useCount } from "../components/context";

export default function Home() {
  const { increment, count, decrement } = useCount();
  return (
    <div className={styles.container}>
      <button onClick={increment}>Increment</button>
      <h1>{count}</h1>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

If you try it in the browser, you won't be able to increment or decrement a number because we don't have the provider as a prop in the page.

To make it work, add

Home.provider = CountProvider;
Enter fullscreen mode Exit fullscreen mode

After reloading the page, you can increment and decrement the number.

Source code

Discussion (2)

Collapse
heywirdgirl profile image
van Manh

thank very much

Collapse
ivanjeremic profile image
Ivan Jeremic

Just wrap components that need state nothing more, not the whole app

Forem Open with the Forem app