1

My setup is as following. I have a layout component where I add a navigation component and children. I wrap them with my Provider like this

AppLayout.js

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

Now the <Navigation/> component has access to the data returned by React.useContext(ContextProvider). However a child component of Layout does not! If I try to console.log(state) in the <Navigation/> component I get back the actual data as expected.

But when I have a child component like this:

Child.js

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

The state is always undefined. The only way I managed to solve this issue was by wrapping the Provider around the Component in the _app.js file. Does anyone know how to solve this without wrapping the provider around the <Component/> from _app.js file?

1 Answer 1

2
+50

That is not possible.
Every component that should have access to one context MUST be descendants of THE SAME context provider.

If you put the context provider inside a wrapper component, and this wrapper component is used in multiple different positions, each instance has a separate context provider, which is a different state. That just does not work.

If you do not want your context provider to be in _app.js, then you may put it inside any child component, but still every component that wants to use the state has to be a descendant of the context provider.

e.g.:

<App>
    <NoDoesNotHaveStore />
    <ContextProvider store={ myStore }>
        <YesDoesHaveStore />
        <YesAlsoDoesHaveStore />
    </ContextProvider>
</App>

You may wrap the context provider:

const SomeWrapper = function(props){
    return <ContextProvider store={ myStore }>
       { props.children }
    </ContextProvider>;
};

<App>
    <NoDoesNotHaveStore />
    <SomeWrapper>
        <YesDoesHaveStore />
        <YesAlsoDoesHaveStore />
    </SomeWrapper>
    <NoStoreAgain />
</App>

But not multiple times:

const SomeWrapper = function(props){
    return <ContextProvider store={ myStore }>
       { props.children }
    </ContextProvider>;
};

<App>
    <SomeWrapper>
        <HasStoreA />
    </SomeWrapper>
    <SomeWrapper>
        <HasDifferentStoreB />
    </SomeWrapper>
</App>

Also note that in Next.js, under certain circumstances, the store might be different on server side vs. client side, or on first render vs. clicking a Next-Link.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.