Reputation: 147
I hope I am capable to explain my question in a understandable way.
I am very new to React! And I am not familiar with how some things get done yet.
I have a GamePage
component. On this page I am rendering a GameRound
component.
When the game starts, a new "game round" starts. After the game round has finished, I want a second and then a third game round to start. This means I need to get kind of a "new" GameRound
. The GamePage
should remain.
While writing this, I got an idea of how this could be achieved: In my gameRoundFinished()
event, I could reset the state of the GameRound. But is that already the most elegant and especially the Reactive way doing this?
Thanks in advance.
Some code as requested...
GamePage.js
export class GamePage extends React.Component {
constructor(props) {
super(props);
// Set game configuration and data
this.state = {
gameId: props.match.params.gameId,
settings: {
categories: ['Stadt', 'Land', 'Fluss'],
countdown: 5
},
activePlayers: {},
game: null
};
// Open socket
this.socket = openSocket('http://localhost:3000');
this.socket.emit('join', this.state.gameId);
this.socket.on('updatePlayers', players => {
this.state.activePlayers = players;
this.setState(this.state);
});
this.socket.on('startGame', () => {
this.state.game = {
rounds: []
};
this.state.game.rounds.push({
});
this.setState(this.state);
});
}
onClick = () => {
this.socket.emit('ready');
}
render() {
if (this.state.game) {
return (
<GameRound socket={this.socket} config={this.state}></GameRound>
);
} else {
return (
<div>Currently {this.state.activePlayers.length}/3
<Button onClick={this.onClick}>klick</Button></div>
);
}
}
}
GameRound.js
export class GameRound extends React.Component {
// too much code that is irrelevant for the question
render() {
return ...
}
}
Upvotes: 0
Views: 281
Reputation: 83587
One solution is to design GameRound
so that it accepts props to determine its behavior. Then to "reset", you just pass the appropriate values for the props to set it to the new round.
Upvotes: 0
Reputation: 21873
Before other things it is necessary to clean the code:
To call functions together with synthetic events in the render method:
<Button onClick={this.onClickEvent()}>click</Button></div>
To use this.setState({ a: 123 })
for changing this.state
object, but not to use this.state
itself for changing the state.
Good example:
this.setState({ activePlayers: players });
Bad examples
this.setState(this.state);
this.state.game = { rounds: [] };
this.state.game.rounds.push({ ... });
You may want to use socket.on()
function to change your state as follows:
socket.on(){
...
this.setState({ activePlayers: players });
}
<Button onClick={this.socket.on()}>click</Button></div>
Upvotes: 0
Reputation: 7819
A very simple way to "reset" a component (and re-run the constructor) is to use the key
prop.
See https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key
In your case: be sure to provide a new key at every round change: something like:
<GameRound key={roundId} socket={this.socket} config={this.state}></GameRound>
Upvotes: 1