2016-03-05 41 views
1

我有一个组件,我在使用一些jQuery来创建基于已经呈现的div的新输入字段。我仍然在学习反应,并且我得到了两个有效但不相等的节点具有相同data-reactid的错误。我知道它是因为我只是将同一个div克隆回dom,但是有关解决此问题的基本方法的任何提示?一直在看着钥匙,但不知道如何把它们放在适当的位置。提前致谢。“两个有效但不相等的节点具有相同的'data-reactid`” - 如何修复

组件:

var AddNew = React.createClass({ 
    getInitialState: function() { 
    return {name: '', quantity: '', price: ''} 
    }, 
    nameChange: function(e) { 
    this.setState({name: e.target.value}); 
    }, 
    quantityChange: function(e) { 
    this.setState({quantity: e.target.value}); 
    }, 
    priceChange: function(e) { 
    this.setState({price: e.target.value}); 
    }, 
    createNewInput: function(e) { 
    e.preventDefault(); 
    $(".add-new:last").clone().insertAfter("div.add-new:last"); 
    }, 
    render: function() { 
    return (
     <div> 
     <div className="new-section"> 
     <div className="add-new"> 
      <ul> 
      <li> 
       <label>Name</label> 
       <input className="add-name" type="text" value={this.state.name} onChange={this.nameChange} /> 
      </li> 
      <li> 
       <label>Quantity Available</label> 
       <input id="quantity" type="number" value={this.state.quantity} onChange={this.quantityChange} /> 
      </li> 
      <li> 
       <label>Price</label> 
       <input id="price" type="number" value={this.state.price} onChange={this.priceChange} /> 
      </li> 
      </ul> 
     </div> 
     </div> 
     <button className="add-another" onClick={this.createNewInput}>+ Add another Input</button> 
     </div> 
    ); 
    } 
}); 

回答

2

我推荐一个更 “被动” 的方式。

代替使用jquery的:

  • 初始化状态与阵列(以存储多组输入项的状态)
  • 呈现来自阵列
  • 元素时Add another set of inputs按钮被点击,一个新的空对象{name: '', quantity: '', price: ''}被添加到数组中并立即渲染,因为每次状态改变时都会调用渲染方法。

您为数组中的每个对象呈现的html输入和其他标记都应该包含在一个html元素中,比如div。如果你把一个key属性的唯一值赋给这个div,你将会摆脱data reactid错误。

但更好地展示代码中,我脑子里想的(你也可以看到它在这里的行动:https://jsbin.com/tinoda/edit?js,console,output):

var AddNew = React.createClass({ 
    getInitialState: function() { 
    return {elements:[]} 
    }, 
    nameChange: function(index, e) { 
    var elements = this.state.elements; 
    elements[index].name = e.target.value; 

    this.setState({elements: elements}); 
    console.log(this.state.elements); 
    }, 
    quantityChange: function(index, e) { 
    var elements = this.state.elements; 
    elements[index].quantity = e.target.value; 

    this.setState({elements: elements}); 
    console.log(this.state.elements); 
    }, 
    priceChange: function(index, e) { 
    var elements = this.state.elements; 
    elements[index].price = e.target.value; 

    this.setState({elements: elements}); 
    console.log(this.state.elements); 
    }, 
    createNewSet: function(e) { 
    var elements = this.state.elements; 
    elements.push({name: '', quantity: '', price: ''}); 

    this.setState({elements: elements}); 
    }, 
    render: function() { 
    return (
     <div className="new-section"> 
     {this.state.elements.map((element, index) => 
      <div key={index}> 
      <div> 
       <label>Name</label> 
       <input className="add-name" type="text" value={element.name} onChange={this.nameChange.bind(this, index)} /> 
      </div> 
      <div> 
       <label>Quantity Available</label> 
       <input className="add-name" type="text" value={element.quantity} onChange={this.quantityChange.bind(this, index)} /> 
      </div> 
      <div> 
       <label>Price</label> 
       <input className="add-name" type="text" value={element.price} onChange={this.priceChange.bind(this, index)} /> 
      </div> 
      </div> 
     )} 

     <button className="add-another" onClick={this.createNewSet}>+ Add another set of inputs</button> 
     </div> 
    ); 
    } 
}); 
+0

感谢这个!非常感激。与React相当新,我不想加入jquery。但是这解决了它。 – luke

+0

再次感谢亚历山德鲁。只是想知道,如何让输入先用下面的按钮来添加更多内容。现在你必须点击按钮才能显示任何输入。我希望输入在加载时显示,然后单击按钮添加任何其他项目。 – luke

+1

欢迎,很高兴帮助!获取负载上的输入设置的较小变化。在'getInitialState'中返回'{elements:[{name:'',quantity:'',price:''}]}'而不是'{elements:[]}''。这样您就可以用包含一组输入空值的数组来初始化组件的状态。当组件被安装时,'getInitialState'函数只被调用一次。充分的工作示例[这里](http://codepen.io/alexchiri/pen/BKjJYj)。 –

相关问题