Reactjs 是否有方法使用ES6类将react组件重置为其初始状态?

Reactjs 是否有方法使用ES6类将react组件重置为其初始状态?,reactjs,Reactjs,我正在编写一个游戏,当游戏结束时,我希望它重置为初始状态。我在文档中没有找到任何有意义的信息,所以我一直在尝试向我的游戏类添加一个重置方法。首先,我尝试执行以下操作,希望创建一个可以稍后扩展的基类,但使用变量作为组件名称失败: class Game extends React.Component { constructor(props) { super(props); this.state = { ... }; } reset() { v

我正在编写一个游戏,当游戏结束时,我希望它重置为初始状态。我在文档中没有找到任何有意义的信息,所以我一直在尝试向我的游戏类添加一个重置方法。首先,我尝试执行以下操作,希望创建一个可以稍后扩展的基类,但使用变量作为组件名称失败:

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);
    }
  }

  ...
}
类游戏扩展React.Component{
建造师(道具){
超级(道具);
此.state={
...
};
}
重置(){
var node=ReactDOM.findDOMNode(this),
ComponentName=this.constructor.name;
如果(节点){
ReactDOM.unmountComponentAtNode(节点);
render(,节点);
}
}
...
}
我继续,并尝试按如下方式硬编码组件名称:

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);
    }
  }

  ...
}
类游戏扩展React.Component{
建造师(道具){
超级(道具);
此.state={
...
};
}
重置(){
var node=ReactDOM.findDOMNode(this);
如果(节点){
ReactDOM.unmountComponentAtNode(节点);
render(,节点);
}
}
...
}
这确实很有效,但我想知道是有一种内置的方法更好,还是更通用的方法。

更新 请忽略前面的答案,replaceState在ES2015类模式中显然不可用。无论如何,另一个解决方案是将游戏实例保持在包装器组件的状态

工作小提琴:

当你重置为新游戏时,这只会将旧游戏从应用程序状态中移除,新游戏将取代它

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>
    );
  }
}
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.newGame=this.newGame.bind(this);
此.state={
游戏:()=>
};
}
新游戏(){
这是我的国家({
游戏:()=>
});
}
渲染(){
const ActiveGame=this.state.game;
返回(
重置游戏
);
}
}
类游戏扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
福:“酒吧”
};
this.onButtonClick=this.onButtonClick.bind(this);
}
onButtonClick(){
这是我的国家({
有些东西是:“你好”,
福:“换了福”
});
}
渲染(){
返回(
设置状态
state.foo:{this.state.foo}

state.somethingElse:{this.state.somethingElse | | |'(尚未定义)}

); } }
如果只需要重置
状态
,则可以将默认状态移动到某个函数或变量中,当需要重置状态时,只需使用此函数或变量的值调用
设置状态

例如:

class Game extends React.Component {
    constructor(props) {
        super(props);
        this.state = this.getState(); // set state from getState result
        this.onButtonClick = this.onButtonClick.bind(this);
        this.onReset = this.onReset.bind(this);
    }

    getState() {
        return {
            number: 0
        }
    }

    onReset() {
        this.setState(this.getState()) // set state from getState result
    }

    onButtonClick () {
        this.setState({
            number: this.state.number + 1
        });
    }

    render () {
        return (
            <div>
                <button onClick={this.onButtonClick}>
                    Increment
                </button>
                <p>{this.state.number}</p>

                <button onClick={this.onReset}>
                    Reset
                </button>
          </div>
        );
    }
}
类游戏扩展React.Component{
建造师(道具){
超级(道具);
this.state=this.getState();//从getState结果设置状态
this.onButtonClick=this.onButtonClick.bind(this);
this.onReset=this.onReset.bind(this);
}
getState(){
返回{
编号:0
}
}
onReset(){
this.setState(this.getState())//从getState结果设置状态
}
onButtonClick(){
这是我的国家({
编号:this.state.number+1
});
}
渲染(){
返回(
增量
{this.state.number}

重置 ); } }

我刚刚使用setState应用了另一个解决方案,并对状态自身的属性进行了迭代,将它们设置为
未定义的
,这对我来说很好:

class Example extends React.Component
{
    constructor(props){
        super(props);
        this._handleInputChange = this._handleInputChange.bind(this);
        this._submitHandler = this._submitHandler.bind(this);
        this._resetHandler = this._resetHandler.bind(this);
        this._setInitialState = this._setInitialState.bind(this);
        this.state = this._setInitialState();
    }
    _resetHandler(){
        this.setState((prevState, props) => {
            var newState = {};
            for( var key in prevState ) {
                if ( prevState.hasOwnProperty(key) ) {
                    newState[key] = undefined;
                }
            }
            if( typeof this._setInitialState === 'function' ){
                Object.assign(newState, this._setInitialState());
            }
            return newState;
        });
    }

    _setInitialState(){
            return {
                mode: 'advanced',
                created: {},
                changed: {}
            };
    }

    _handleInputChange(){
        // do stuff to change the state
    }
}
其中_setInitialState返回应用程序运行所需初始化的所有属性


这结合了不需要在初始值设定项对象中维护状态的完整轮廓的优点,同时也不需要在重置时重新安装组件的开销。

使用ES6类时,不存在replaceState。这不会删除在游戏运行时添加的任何新状态属性,可能会导致问题。@dannyjolie是的,但更好的方法是将所有可能的状态键添加到默认状态,而不是完全重新安装组件;对但是,您必须记住保持基本状态对象与组件的其余部分同步。在现实世界中,您将在几个月内进行一些重构,添加一些新的状态属性,等等,甚至更糟的是,其他人将处理代码。如果您忘记将新的状态属性添加到基本状态,则不会显示任何警告,因此为了将来的证明,仅销毁整个内容并创建新的游戏实例是一种不太容易出错的解决方案。这几乎就像setState需要将第二个参数作为布尔值;如果为真,则替换状态,如果为假或忽略,则按常规设置状态。我更倾向于同意@dannyjolie,因为它更干净,而且100%确保如果某个地方出现了与最佳实践不符的情况,它会得到处理。这是另一个解决由糟糕的体系结构引起的问题的复杂方法。