NextJS 使用 React 的 Context API 和布局组件包装器
NextJS using React's Context API with a layout component wrapper
我的设置如下。我有一个布局组件,我在其中添加了一个导航组件和子组件。我像这样用我的提供者包装它们
AppLayout.js
<Layout>
<Navigation/>
<main>
{children}
</main>
</Layout>
现在 <Navigation/>
组件可以访问 React.useContext(ContextProvider)
返回的数据。
但是 Layout 的子组件不会!如果我尝试在 <Navigation/>
组件中 console.log(state)
我会按预期取回实际数据。
但是当我有这样的子组件时:
Child.js
<AppLayout>
<div>Some content</div>
</AppLayout>
状态始终未定义。我设法解决此问题的唯一方法是将 Provider 包装在 _app.js
文件中的 Component 周围。有谁知道如何在不将提供者包装在 _app.js
文件中的 <Component/>
周围的情况下解决这个问题?
那是不可能的。
应有权访问一个上下文的每个组件都必须是同一上下文提供程序的后代。
如果你把context provider放在一个wrapper组件里面,这个wrapper组件用在多个不同的位置,每个实例都有一个单独的context provider,这是一个不同的状态。那是行不通的。
如果您不希望您的上下文提供程序位于 _app.js 中,那么您可以将它放在任何子组件中,但仍然每个想要使用状态的组件都必须是上下文的后代提供商。
例如:
<App>
<NoDoesNotHaveStore />
<ContextProvider store={ myStore }>
<YesDoesHaveStore />
<YesAlsoDoesHaveStore />
</ContextProvider>
</App>
您可以包装上下文提供程序:
const SomeWrapper = function(props){
return <ContextProvider store={ myStore }>
{ props.children }
</ContextProvider>;
};
<App>
<NoDoesNotHaveStore />
<SomeWrapper>
<YesDoesHaveStore />
<YesAlsoDoesHaveStore />
</SomeWrapper>
<NoStoreAgain />
</App>
但不是多次:
const SomeWrapper = function(props){
return <ContextProvider store={ myStore }>
{ props.children }
</ContextProvider>;
};
<App>
<SomeWrapper>
<HasStoreA />
</SomeWrapper>
<SomeWrapper>
<HasDifferentStoreB />
</SomeWrapper>
</App>
另请注意,在 Next.js 中,在某些情况下,商店可能在服务器端与客户端不同,或者在首次呈现与单击 Next-Link.
我的设置如下。我有一个布局组件,我在其中添加了一个导航组件和子组件。我像这样用我的提供者包装它们
AppLayout.js
<Layout>
<Navigation/>
<main>
{children}
</main>
</Layout>
现在 <Navigation/>
组件可以访问 React.useContext(ContextProvider)
返回的数据。
但是 Layout 的子组件不会!如果我尝试在 <Navigation/>
组件中 console.log(state)
我会按预期取回实际数据。
但是当我有这样的子组件时:
Child.js
<AppLayout>
<div>Some content</div>
</AppLayout>
状态始终未定义。我设法解决此问题的唯一方法是将 Provider 包装在 _app.js
文件中的 Component 周围。有谁知道如何在不将提供者包装在 _app.js
文件中的 <Component/>
周围的情况下解决这个问题?
那是不可能的。
应有权访问一个上下文的每个组件都必须是同一上下文提供程序的后代。
如果你把context provider放在一个wrapper组件里面,这个wrapper组件用在多个不同的位置,每个实例都有一个单独的context provider,这是一个不同的状态。那是行不通的。
如果您不希望您的上下文提供程序位于 _app.js 中,那么您可以将它放在任何子组件中,但仍然每个想要使用状态的组件都必须是上下文的后代提供商。
例如:
<App>
<NoDoesNotHaveStore />
<ContextProvider store={ myStore }>
<YesDoesHaveStore />
<YesAlsoDoesHaveStore />
</ContextProvider>
</App>
您可以包装上下文提供程序:
const SomeWrapper = function(props){
return <ContextProvider store={ myStore }>
{ props.children }
</ContextProvider>;
};
<App>
<NoDoesNotHaveStore />
<SomeWrapper>
<YesDoesHaveStore />
<YesAlsoDoesHaveStore />
</SomeWrapper>
<NoStoreAgain />
</App>
但不是多次:
const SomeWrapper = function(props){
return <ContextProvider store={ myStore }>
{ props.children }
</ContextProvider>;
};
<App>
<SomeWrapper>
<HasStoreA />
</SomeWrapper>
<SomeWrapper>
<HasDifferentStoreB />
</SomeWrapper>
</App>
另请注意,在 Next.js 中,在某些情况下,商店可能在服务器端与客户端不同,或者在首次呈现与单击 Next-Link.