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>
)
}