为什么我的州在这里更新?

时间:2016-06-06 10:21:18

标签: reactjs

我对React很新,但到目前为止还喜欢它。我正在构建一个很好的应用程序,除了我遇到了一个问题。我正在建立一个问题回答列表,可以删除它们,但我也希望有一个“取消”按钮,以便可以恢复所有未保存的更改。让我感到困惑的是取消按钮恢复到名称值的初始状态,而不是响应。如果我将一些控制台日志记录添加到响应删除脚本中,我希望看到日志行1& 2匹配,3与不同。但是,我看到1是原始的,但2& 3场比赛。为什么在调用setState之前状态被更新,为什么更新状态似乎更新了我的初始道具?

编辑:我添加了jsFiddle

getInitialState: function() {
  return {
    name: this.props.question.name,
    responses: this.props.question.responses,
  };
},
handleCancelButtonClick: function(e) {
    this.replaceState(this.getInitialState());
},
handleNameChange: function(e) {
    this.setState({name: e.target.value});
},
handleResponseDeletion: function(e) {
    var resp = this.state.responses;
    var from = Number(e.target.value);
    console.log(JSON.stringify(this.state.responses));
    resp.splice(from, 1);
    console.log(JSON.stringify(this.state.responses));
    this.setState({responses: resp});
    console.log(JSON.stringify(this.state.responses));
},
render: function() {
    var key = "mp" + this.props.question.name;
    var resp = [];
    if (this.state.responses) {
        this.state.responses.forEach(function(response, i) {
            var rkey = "r_" + this.props.question.name + "_" + i;
            resp.push(<ModalResponse response={response} key={rkey} value={i} deleteResponse={this.handleResponseDeletion} />);
                }.bind(this));
        }
        return (
            <layer id={this.props.question.name} style={questionModal} key={key}>
                <h2>Edit {this.state.name}</h2>
                <button onClick={this.handleCancelButtonClick}>Cancel</button>
                <div class='form-group'>
                    <label for='client_name' style={formLabel}>Question Name:</label><br />
                    <input type='text' style={formControl} id='question_name' name='question_name' value={this.state.name} onChange={this.handleNameChange} required />
                </div>
                <div class='form-group'>
                    <label  style={formLabel}>Responses:</label><br />
                    <ul style={responseList} type="response_list" value={this.props.qname}>                       
                        {resp}
                    </ul>
                </div>
            </layer>                            
        );
    }
});

2 个答案:

答案 0 :(得分:0)

问题是splice修改了原始数组。它表示属于原始question的那个。因此,当您从getInitialState内拨打handleCancelButtonClick时,您会获得修改后的数组。

为避免这种情况,您需要以某种方式克隆getInitialState内的原始数据。例如

getInitialState: function() {
  //copy array and responses
  const copy = resp => ({...resp})

  return {
    name: this.props.question.name,
    responses: this.props.question.responses.map(copy)
  };
}

答案 1 :(得分:0)

以下是解决问题的方法:

handleResponseDeletion: function(e) {
  var resp = []
  var from = Number(e.target.value);
  this.state.responses.forEach(function(res, i) {
    if (i != from) {
        resp.push(res);
    }
  });
  this.setState({responses: resp});
},