reactjs Next.js上下文提供程序使用提供未定义数据的页面特定布局组件 Package 应用程序组件

gkl3eglg  于 2022-11-04  发布在  React
关注(0)|答案(2)|浏览(126)

我有一个auth上下文组件,我在其中 Package 了我的主要应用程序组件,但同时我也在尝试根据Next.js文档做页面特定的布局组件,如下所示:https://nextjs.org/docs/basic-features/layouts#per-page-layouts
我这样做是否正确,因为我似乎无法从我的上下文提供者获取数据。

/上下文/身份验证上下文.js

const UserContext = createContext({});

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

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

/_应用程序.js

function MyApp({ Component, pageProps }) {    

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

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

export default MyApp;

/组件/项目/列表.js

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

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

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

export default ProjectList;

我试着控制台记录用户,但是它给了我undefined。我想这是因为它被 Package 成布局组件的方式吗?我可能做错了。但是我在我的AuthContext for user中做了控制台记录,那里的信息是正确的。

/页面/项目/索引.js

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

export default Projects;

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

当我删除Projects.getLayout代码块时,数据回来了,但是当我添加这段代码时,数据不见了。

/组件/项目/布局.js

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

export default ProjectLayout
but5z9lq

but5z9lq1#

对于当前的结构,ProjectLayout没有被AuthContext Package ,这意味着您将无法访问它的上下文。
您可以修改_app的结构并移动getLayout调用,以便上下文正确 Package 它。

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

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

ldxq2e6h2#

在上下文内调用getLayout可能会导致错误。它首先调用getLayout,然后调用上下文,因此它的值最初将是默认值(回退)(这就像执行foo(bar()),并期望在bar之前调用foo)。See this issue in Next.js explaining this problem
若要避免此问题,请将布局用作组件:

// /pages/projects/index.js
Projects.Layout = ({ children }) => {
  return <ProjectLayout>{children}</ProjectLayout>;
};

// /pages/_app.js
export default function App({ Component, pageProps }) {    
    const Layout = Component.Layout || (({ children }) => children);
    return (
        <AuthContext>
            <Layout>
                <Component {...pageProps} />
            </Layout>
        </AuthContext>
    );
}

相关问题