I have a architecture of a React application as follows:
<GrandParentComponent>
<ParentComponent>
<ChildComponent>
</ParentComponent>
</GrandParentComponent>
The child component is creating a context within itself to be shared with all its internal components.
I have a ref being passed as a useCallback() from the <ParentComponent> to the <ChildComponent> to keep track of a state which is being passed from the <GrandparentComponent>.
GrandParent
const [isPlaying, setIsPlaying] = useState(false);
return (
<>
{ isPlaying ? "True" : "False" }
<ParentComponent {...{isPlaying, setIsPlaying}}/>
</>
);
Parent
const [button, setButton] = useState();
const handleRef = useCallback( current => {
if(current) {
setButton(current.button);
}
}, []);
useEffect(() => {
if(button) {
const callback = ({type}) => setIsPlaying(type === "play");
button.addEventListener("play", callback);
return () => {
button.removeEventListener("play", callback);
};
}
}, [button]);
return (
{ isPlaying ? "True" : "False" }
<ChildRoot>
<Child ref={handleRef}/>
</ChildRoot>
);
Child
const export ChildRoot = ({children}) => {
return (
<ChildContext.Provider value={{
isOpen: true,
setIsOpen: () => {}
}}
/>
{children}
</ChildContext.Provider>
);
};
const export Child = ({}, forwardRef) => {
const ref = useRef();
useImperativeHandle(forwardRef, () => ({
get button() {
return ref.current();
}
})
});
For some reason the value of isPlaying is only reflected in the <ParentComponent> but not in the <GrandParentComponent>. I've tried using a useContext() and that hasn't solved this either.
How do I make sure that the state is consistent?