NextJS использует контекстный API-интерфейс React с оболочкой компонента компоновки

#reactjs #next.js #react-context

#reactjs #next.js #реагировать-контекст

Вопрос:

Моя настройка выглядит следующим образом. У меня есть компонент макета, в который я добавляю компонент навигации и дочерние элементы. Я оборачиваю их своим провайдером следующим образом

AppLayout.js

 <Layout>
  <Navigation/>
  <main>
    {children}
  </main>
</Layout>
 

Теперь <Navigation/> компонент имеет доступ к данным, возвращаемым React.useContext(ContextProvider) .
Однако дочерний компонент Layout этого не делает! Если я попытаюсь console.log(state) в <Navigation/> компоненте, я получу обратно фактические данные, как и ожидалось.

Но когда у меня есть дочерний компонент, подобный этому:

Child.js

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

Состояние всегда не определено. Единственный способ, которым мне удалось решить эту проблему, — обернуть поставщика вокруг компонента в _app.js файле. Кто-нибудь знает, как решить эту проблему, не оборачивая поставщика вокруг файла <Component/> from _app.js ?

Ответ №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 , при определенных обстоятельствах хранилище может отличаться на стороне сервера и на стороне клиента или при первом рендеринге и при нажатии на следующую ссылку.