![](/img/trans.png)
[英]Next.js Opt out of Layout Component for specific pages from _app.js
[英]Next.js context provider wrapping App component with page specific layout component giving undefined data
我有一个身份验证上下文组件,我在其中包装了我的主要应用程序组件,但同时我也在尝试根据 Next.js 文档在此处执行页面特定布局组件:https://nextjs.org/docs/basic-features /layouts#per-page-layouts
我这样做是否正确,因为我似乎无法从我的上下文提供程序获取数据。
/上下文/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;
/组件/项目/List.js
import { useUser } from "../../context/AuthContext";
const ProjectList = () => {
const { user } = useUser();
console.log("get user data", user);
return (
<>
test
</>
);
};
export default ProjectList;
我正在尝试控制台登录用户,但它给了我未定义的信息。 我在想这是因为它作为布局组件的包装方式? 我可能做错了。 但是我在我的AuthContext
中为用户做了控制台登录,那里的信息是正确的。
/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>;
};
当我删除Projects.getLayout
代码块时,数据又回来了,但是当我添加这段代码时,数据就消失了。
/组件/项目/Layout.js
const ProjectLayout = ({children}) => {
return (
<>
<ProjectList />
{children}
</>
}
export default ProjectLayout
使用您当前的结构ProjectLayout
不会被AuthContext
包裹,这意味着您将无法访问其上下文。
您可以修改_app
的结构并移动getLayout
调用,以便上下文正确包装它。
function MyApp({ Component, pageProps }) {
const getLayout = Component.getLayout || ((page) => page);
return (
<AuthContext>
{getLayout(<Component {...pageProps} />)}
</AuthContext>
);
}
请注意,如果getLayout
function 使用挂钩或依赖于父元素的内容,则在 Context 中调用getLayout
可能会导致错误。
它将首先调用getLayout
然后调用上下文,因此它的值最初将是默认(后备)值(就像执行foo(bar())
并期望foo
将在bar
之前被调用)。
为了避免这种情况,直接返回组件(使用getLayout
作为生成组件的 function):
// /pages/projects/index.js
Projects.getLayout = (children) => (
// can't use hooks here, return the component immediately
<ProjectLayout>{children}</ProjectLayout>;
);
或将布局用作组件:
// /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>
);
}
编辑:没有 JSX 时差异更明显
// incorrect
return React.createElement(AuthContext, null,
// getLayout is called before AuthContext
getLayout(
React.createElement(Component, pageProps)
)
)
// correct
return React.createElement(AuthContext, null,
// Layout is called after AuthContext
React.createElement(Layout, null,
React.createElement(Component, pageProps)
)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.