Home > Back-end >  React App does not update context but all children do
React App does not update context but all children do

Time:10-30

I am trying to understand react better so I created a sandbox example to play with. I basically have this structure App->Child->Grandchild. I created my context then wrapped App in the provider, then used the context in each component. When I set the context in the child, the child and the grandchild get updated and the context looks different from the App. If I set the context in the grandchild, neither the child or App get updated. Here is what the context looks like in the child and grandchild:

  {convo: "A happy family is but an earlier heaven...", speak: ƒ speak()}

But in App I just get a string back, Not an object:

    IN CONTEXT: this works for direct children of the provider

My console.log looks like this:

 const text = useContext(ConvoContext);
 console.log("child:", text);

So it appears when context is set it only works for the children where it is set at?

Here is my code sandbox I've been playing with:

https://codesandbox.io/s/context-example-ecs92?file=/src/App.js:0-774

CodePudding user response:

Your ContextProvider always should be the highest parent of all Components and you just can update its state inside children of the Context.

export CustomContext = React.createContext()

const CustomContextProvider = (props) => {
  let [convo, setConvo] = useState("For all children")

  return (
   <CustomContext.Provider value={{convo, setConvo /* rest of methods and states */}}>
     {props.children}
   </CustomContext.Provider>
  )
}

If you need your App component to be the first child of your Context you should change to something like this.

const App = (props) => {
  const context = useContext(CustomContext);
  /* update hooks for context changes and local changes are going here */
  return <Child></Child>
}

At the last, you would wrap your app inside the context provider.


export const AppWithContexProvider = (props) => {
  return (
    <CustomContextProvider>
     <App />
    </CustomContextProvider>
  )
}

If you have another Context that is updating due to your last CustomContext you should add it inside that.

export const AnotherContext = createContext()
export AnotherCustomContextProvider = (props) => {
   const [state, setState] = useState(0);
  /* also use a parnet context */
  let [parentState, setParentState] = useContext(CustomContext)
 return (
   <AnotherCustomContextProvider.Provider value={{setState}}>
     {props.children}
   </AnotherCustomContextProvider.Provider>
 )
}

Again add your child context and so on.

export const AppWithContexProvider = (props) => {
  return (
    <CustomContextProvider>
     /* this one can update convo value */
     <AnotherCustomContextProvider>
      <App />
     </AnotherCustomContextProvider>
    </CustomContextProvider>
  )
}
  • Related