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