This is a very broad question. I'll answer it with my own opinion about how I would likely handle a situation like this.
Since React 16.3, I've found the built-in context api to be easier to work with, and more powerful, than Redux. This is how I would setup the context provider:
const DEFAULT_STATE = {
gameMode: 'default',
players: [],
currentRound: 1,
...
};
export const MyContext = React.createContext(DEFAULT_STATE);
export const MyConsumer = MyContext.Consumer;
class MyProvider extends Component {
state = DEFAULT_STATE;
componentDidMount() {
// query your api on app start here
}
render() {
return (
<MyContext.Provider
value={{
state: this.state,
setState: (name, value, callback = () => {}) => {
this.setState({ [name]: value }, callback);
},
incrementRound: () => {
const { currentRound } = this.state;
this.setState({ currentRound: currentRound + 1 });
},
// any other functions you want to expose to your consumer
}}
>
{this.props.children}
</MyContext.Provider>
}
};
export default MyProvider;
You could then setup your root component like this:
ReactDOM.render(
<MyProvider><App /></MyProvider>,
document.getElementById('root')
);
Then you can access your context/consumer in any of your other components:
class SomeComponent extends Component {
state = {/* component state */};
incrementRound = (context) => {
// option a: access state directly
const { currentRound } = context.state;
context.setState('currentRound', currentRound + 1);
// option b: expose function to handle state
context.incrementState();
};
render() {
return (
<section>
<div>{/* some other stuff */}</div>
<MyConsumer>
{context => {
const { currentRound } = context.state;
return (
<div>{currentRound}</div>;
<button>Click to update round!</button>
);
}}
</MyConsumer>
</section>
);
}
}
This is a very simple example, but I think it gets the point across. If you go this route, I would also recommend exporting your state keys from your DEFAULT_STATE object so that you don't have call setState with literal strings. You could do something like this:
const stateKeysObj = {};
Object.keys(DEFAULT_STATE).forEach(key => {
stateKeysObj[key] = key;
});
export const stateKeys = Object.freeze(stateKeysObj);
Good luck with your game!