如何正确删除输入列表中的输入字段

时间:2017-06-23 09:53:18

标签: reactjs

我正在尝试动态处理输入列表。但是当我在输入中放入一些内容并从列表中删除一个内容时,我有一个不受欢迎的行为。删除了正确的项目,但最后一个位置的项目采用上一项目的状态。



var ListItem = React.createClass({
  
  getInitialState: function() {
  	return {
    	content: ''
    }
  },
  
  handleChange: function(e) {
  	this.setState({
    	content: e.target.value
    })
  },
  
  render: function() {
    return <div>
     	<input type="text" onChange={this.handleChange} />
    </div>
  }
});

var App = React.createClass({
  getInitialState : function(){
    return {
      items : []
    }
  },

  deleteElement: function(index, e) {
    this.setState({
    	items: this.state.items.filter(function (e, i) {
      	return i !== index;
      })
    });
  },

  addElement: function() {   
    this.setState({
    	items: this.state.items.concat(<ListItem />)
    });
  },

  render: function() {
    var list = this.state.items.map(function(item, i) {
      return <li key={ i }>
        <p onClick={ this.deleteElement.bind(this, i) }>(-)</p>
        <span>{ item }</span>
      </li>
    }, this);

    return <div>
      <ul>{ list }</ul>
      <p onClick={ this.addElement }>(+)</p>
    </div>
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('container')
);
&#13;
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>
&#13;
&#13;
&#13;

我认为问题可能与我的列表键有关,但我不明白为什么。如何在不改变任何状态的情况下删除列表元素?

由于

1 个答案:

答案 0 :(得分:3)

在渲染中迭代时,React重用组件实例(出于显而易见的性能原因)。为了区分实例,使用了道具key

在您删除元素的情况下,索引会移动,因此您会混淆key -> instance关联。因此,删除元素之后的列表项不再与正确的实例相关联,这就是为什么某些列表元素似乎具有前一个元素的状态。

要避免此问题,您应该永远不要将索引用作关键支柱。请改为使用数据实例的唯一标识符。

在您的情况下,您可以在添加新元素时生成唯一标识符,并将其用作键。

有关列表如何在React中工作的详细信息,请阅读:https://facebook.github.io/react/docs/lists-and-keys.html