Have you ever wanted two separate components that share common state? Maybe a controller component and a display component where one component deals with the controls and the other with displaying it. Something like this:
const [a, setA] = useState()
...
...
...
(
<Box className="grid gap-4" style={{ gridTemplateColumns: "1fr 1fr" }}>
<GameGrid a={a} b={b} c={c}/>
<GameControls setA={setA} setB={setB} setC={setC}/>
</Box>
)
It might be okay if we just pass a couple props, but even with few props it feels wrong. So, how do we do it?
Share context between sibling components.
To do this you need to create a context object and wrap the components in it. And then you can get the context in each object, regardless of where you manage the sate.
const GameContext = createContext<IGameControls>({
a: 'x'
setA: () => void
....
});
export const Game = () =>{
const contextValue: IGameControls = {
a,
setA,
b,
setB,
....
};
return (
<GameContext.Provider value={contextValue}>
<Box className="grid gap-4" style={{ gridTemplateColumns: "1fr 1fr" }}>
<GameGrid />
<GameControls />
</Box>
</GameContext.Provider>
);
}
One important thing to pay attention to is that we only share this state between the sibling components, so the rest of the code is not burdened by this data.
And now we can get the context in each component easily:
const { a, setA, .... } = useGameContext();
Top comments (0)