Reputation: 333
I have two contexts - gameContext, roundContext. I am using useReducer to manipulate the state. Can I dispatch action in gameContext from roundContext reducer (RoundReducer)?
The reducer function is defined outside RoundProvider component.
const RoundReducer = (state: RoundStateType, action: any) => {
///sth
}
const RoundProvider: React.FC<{}> = ({ children }) => {
const [state, dispatch] = useReducer(RoundReducer, initState);
return (
<RoundContext.Provider
value={{ roundState: state, roundDispatch: dispatch }}>
{children}
</RoundContext.Provider>
);
};
The GameProvider component looks the same.
Upvotes: 1
Views: 2707
Reputation: 25386
If you have nested contexts GameContext
and RoundContext
you can access the outer game context from the inner round, then call a setter/dispatch method to initiate a change in each. The inner RoundContext provider is inside the GameContext provider, so there (dispatch
in this example) you have access to the methods exposed by the GameContext.
const GameContext = React.createContext(null);
const GameProvider = ({ children }) => {
const [gameState, setGameState] = React.useState();
return (
<GameContext.Provider value={{ gameState, setGameState }}>
{children}
</GameContext.Provider>
);
};
const useGame = () => React.useContext(GameContext)
const RoundContext = React.createContext(null);
const RoundProvider = () => {
const { gameState, setGameState } = useGame();
const [roundState, setRoundState] = React.useState();
const dispatch = (value) => {
// Do something to both the round and the game state
setGameState(value.toUpperCase());
setRoundState(value);
};
return (
<RoundContext.Provider value={{ roundState, dispatch }}>
{children}
</RoundContext.Provider>
);
}
const useRound = () => React.useContext(RoundContext)
const Main = () => {
const game = useGame()
const round = useRound()
const handleAction = () => {
round.dispatch('some value that also goes to the game')
}
return <>
<input type='text' onChange={handleAction} />
<div>{game.gameState}</div>
<div>{round.roundState}</div>
</>
}
const App = () => (<GameProvider>
<RoundProvider>
<Main />
</RoundProvider>
</GameProvider>)
Here's a codesandbox example: https://codesandbox.io/s/xenodochial-wind-gkhje
Upvotes: 2
Reputation: 144
pass the prop from the game context to roundContext or other way around, let say if you're using react hooks - useState,in props pass the setValue.
Please review the following code.
also, this is just for referance
export default function GameComponent(){
//suppose this is parent component and you want to change the value from child componenet
const [value, setValue] = useState("Patel");
return(
<div>
<h1>{value}</h1>
<RoundComponent setValue={setValue} value={value} />
//pass props like this
</div>
)
}
now coming back to round component
export default function RoundComponent(props){
return(
<div>
<input type="text" name="name" value={props.value} onChange={e=>props.setValue(e.target.value)}/>
</div>
)
}
I hope this answers your question.
Upvotes: 0