Skip to content
Advertisement

Next.js context provider wrapping App component with page specific layout component giving undefined data

I have an auth context component where I’m wrapping my main app component, but at the same time I’m also trying to do page specific layout component per Next.js documentation here: https://nextjs.org/docs/basic-features/layouts#per-page-layouts

Am I doing this correctly, because I can’t seem to be getting the data from my Context provider.

/context/AuthContext.js

const UserContext = createContext({});

export default function AuthContext({children}) {
  // .. code
  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
}

export const useUser = () => useContext(UserContext);

/_app.js

function MyApp({ Component, pageProps }) {    

  const getLayout = Component.getLayout || ((page) => page);

  return getLayout(
    <div>
      <AuthContext>
        <Component {...pageProps} />
      </AuthContext>
    </div>
  );
}

export default MyApp;

/components/Project/List.js

import { useUser } from "../../context/AuthContext";

const ProjectList = () => {
  const { user } = useUser();
  console.log("get user data", user);

  return (
    <>
      test
    </>
  );
};

export default ProjectList;

I’m trying to console log the user, but it’s giving me undefined. I’m thinking it’s because the way it’s wrapped as a layout component? I could be doing this wrong. But I did console log inside my AuthContext for user, and the information there is correct.

/pages/projects/index.js

const Projects = () => {
  // code goes here
  return (
    <div>
      code goes here
    </div> 
  )
}

export default Projects;

Projects.getLayout = function getLayout(page) {
  return <ProjectLayout>{page}</ProjectLayout>;
};

When I remove the Projects.getLayout block of code, the data comes back, but when I add this code, data is gone.

/components/Project/Layout.js

const ProjectLayout = ({children}) => {
  return (
    <>
      <ProjectList />
      {children}
    </>
  }

export default ProjectLayout

Advertisement

Answer

With your current structure ProjectLayout isn’t getting wrapped by the AuthContext, meaning you won’t have access to its context.

You can modify your _app‘s structure and move the getLayout call around so that the context wraps it properly.

function MyApp({ Component, pageProps }) {    
    const getLayout = Component.getLayout || ((page) => page);

    return (
        <AuthContext>
            {getLayout(<Component {...pageProps} />)}
        </AuthContext>
    );
}
5 People found this is helpful
Advertisement