According to the react documentation for context provider :
All consumers that are descendants of a Provider will re-render whenever the Provider's value prop changes.
I am trying to update a context value from a sibling component (B) and read that update from sibling component (A).
Heres a simple example of what im trying:
import { useState, useContext, createContext } from "react";
export const AnalyseCtx = createContext({ greeting: "hello" });
export default function App() {
const [context, setContext] = useState({ greeting: "hello" });
console.log("rendering App");
return (
<div className="App">
<AnalyseCtx.Provider value={{ context, setContext }}>
<ComponentA />
<ComponentB />
</AnalyseCtx.Provider>
</div>
);
}
function ComponentA() {
const analyseContext = useContext(AnalyseCtx);
console.log("rendering ComponentA");
return (
<h4>I display the context value: {analyseContext.context.greeting}</h4>
);
}
function ComponentB() {
console.log("rendering ComponentB");
const analyseContext = useContext(AnalyseCtx);
analyseContext.setContext((prevState) => {
prevState.greeting = "updated greeting";
console.log("updated greeting: ", prevState);
return prevState;
});
return <h4>I update context value</h4>;
}
I have also created a codesandbox to demonstrate the issue as well.
Sorry if this is a stupid question, but I've been stuck on this problem for a whole day. Thanks!
Component B is mutating the state object instead of returning a new state object reference. Shallow copy the previous state object into a new object reference and overwrite the properties you want to update.
Another issue is that component B is updating the context value as an unintentional side-effect. The update should be done from the useEffect
hook so it's unconditionally enqueueing state updates and creating conditions for infinite render looping.
function ComponentB() {
const { setContext } = useContext(AnalyseCtx);
useEffect(() => {
setContext(state => ({
...state,
greeting: "updated greeting",
}));
}, []);
return <h4>I update context value</h4>;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.