NextJS 使用带有布局组件包装器的 React 的 Context API

Posted

技术标签:

【中文标题】NextJS 使用带有布局组件包装器的 React 的 Context API【英文标题】:NextJS using React's Context API with a layout component wrapper 【发布时间】:2021-03-22 01:22:38 【问题描述】:

我的设置如下。我有一个布局组件,我在其中添加了一个导航组件和子组件。我像这样用我的 Provider 包装它们

AppLayout.js

<Layout>
  <Navigation/>
  <main>
    children
  </main>
</Layout>

现在&lt;Navigation/&gt; 组件可以访问React.useContext(ContextProvider) 返回的数据。 但是 Layout 的子组件没有!如果我尝试在&lt;Navigation/&gt; 组件中使用console.log(state),我会按预期取回实际数据。

但是当我有这样的子组件时:

Child.js

<AppLayout>
 <div>Some content</div>
</AppLayout>

状态始终未定义。我设法解决此问题的唯一方法是将 Provider 包装在 _app.js 文件中的组件周围。有谁知道如何在不将 &lt;Component/&gt; 文件中的 &lt;Component/&gt; 包装起来的情况下解决这个问题?

【问题讨论】:

【参考方案1】:

这是不可能的。 应该有权访问一个上下文的每个组件都必须是同一上下文提供者的后代。

如果你把上下文提供者放在一个包装器组件里面,而这个包装器组件用在多个不同的位置,每个实例都有一个单独的上下文提供器,这是不同的状态。那是行不通的。

如果你不希望你的上下文提供者在 _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 时可能不同。

【讨论】:

以上是关于NextJS 使用带有布局组件包装器的 React 的 Context API的主要内容,如果未能解决你的问题,请参考以下文章

带有 Chakra UI 的 React-hook-form 未在 NextJS 中显示验证错误消息

使用带有 NextJS 的 Apollo Client 时服务器端渲染数据?

带有 nextjs 的 G2Plot。堆积图不起作用

使用带有布局页面或每页多个组件的 React-Router

具有固定包装器的引导网格 - 防止列堆叠

带有 Bootstrap 的 React 组件的页面布局 - 页脚未保留在原位