2016-03-05 48 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)。 –

相關問題