Omnilord Omnilord - 13 days ago 9
React JSX Question

Is there a method to reset a react component using ES6 classes to its initial state?

I am writing a game and when the game is over, I want it to reset to the initial state. I haven't found any meaningful information in the docs for this, so I've been playing around with adding a reset method to my Game class. First, I attempted doing the follow in hopes of creating a base class I could extend later, but using a variable for the component name fails:

class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
...
};
}

reset() {
var node = ReactDOM.findDOMNode(this),
ComponentName = this.constructor.name;
if (node) {
ReactDOM.unmountComponentAtNode(node);
ReactDOM.render(<ComponentName />, node);
}
}

...
}


I moved on, and tried to hardcode the component name as follows:

class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
...
};
}

reset() {
var node = ReactDOM.findDOMNode(this);
if (node) {
ReactDOM.unmountComponentAtNode(node);
ReactDOM.render(<Game />, node);
}
}

...
}


This works really well, but I am wondering if there is a built-in way that is better, or a more generic way.

Answer

Update Please disregard the previous answer, replaceState is obviously not available in the ES2015 class pattern. Anyway, another solution is to keep an instance of the game in a wrapper component's state.

Working fiddle: https://jsfiddle.net/dannyjolie/upktozt1/1/

This will just remove the old game from App's state when you reset to a new game, and a new game will take its place.

class App extends React.Component {
    constructor(props) {
    super(props);
    this.newGame = this.newGame.bind(this);
    this.state = {
        game: ()=><Game />
    };
  }

  newGame () {
    this.setState({
        game: () => <Game />
    });
  }

    render () {
    const ActiveGame = this.state.game;
    return (
        <div>
        <ActiveGame />
        <button onClick={this.newGame}>RESET GAME</button>
      </div>
    );
  }
}

class Game extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
        foo: 'Bar'
    };
    this.onButtonClick = this.onButtonClick.bind(this);
  }
  onButtonClick () {
    this.setState({
        somethingElse: 'Hello',
      foo: 'Changed foo'
    });
  }
    render () {
    return (
        <div>
        <button onClick={this.onButtonClick}>Set state.somethingElse</button>
        <p>state.foo: {this.state.foo}</p>
        <p>state.somethingElse: {this.state.somethingElse || '(not defined yet)'}</p>
      </div>
    );
  }
}