primarykey123
primarykey123

Reputation: 147

ReactJS: Reload a new instance of the component?

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

Answers (3)

Code-Apprentice
Code-Apprentice

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

Roman
Roman

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

keul
keul

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

Related Questions