skip to Main Content

In the classic Pages Router of Next, You can add a global provider in your _app.js file and wrap it around the entire component tree. This will ensure that the provider is available to all components.

If you do this using the App Router, you get an error message

You’re importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they’re Server Components by default.

Is there a way to achieve something similar without giving up the Server Components?

2

Answers


  1. // use context in _app.js

    // user.js

    import { createContext, useState, useContext } from "react";
    
    const Context = createContext();
    
    const Provider = ({ children }) => {
      const [user, setUser] = useState(true);
    
      const exposed = {
        user,
      };
    
      return <Context.Provider value={exposed}>{children}</Context.Provider>;
    };
    
    export const useUser = () => useContext(Context);
    
    export default Provider;
    

    // _app.js

    import UserProvider from "../context/user";
    
    function MyApp({ Component, pageProps }) {
        return (
            <UserProvider>
                <Component {...pageProps} />
            </UserProvider>
        );
    }
    export default MyApp;
    

    // use user state in any component like this

    import { useUser } from "../context/user";
    
    export default function Home({ lessons }) {
      const { user } = useUser();
      console.log({ user });
      return (
        <div>
          
        </div>
      );
    }
    
    Login or Signup to reply.
  2. Wrap the provider in a client component.

    'use client';
     
    import { SomeProvider } from 'some-library';
     
    export function Providers({ children }) {
      return (
        <SomeProvider>
          {children}
        </SomeProvider>
      );
    }
    

    And use this wrapped provider in root layout.

    import { Providers } from './providers';
     
    export default function RootLayout({ children }) {
      return (
        <html>
          <body>
            <Providers>{children}</Providers>
          </body>
        </html>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search