2017-04-01 142 views
0

所以即時嘗試使反應與ES6語法一起工作。在ES5中,我有setInitialState,沒有使用函數綁定語法的構造函數。我有一個價格列表是任意的,我希望狀態在輸入元素改變時改變。但是正確的價格必須改變。將多個參數傳遞給React中的onChange/onClick函數

我甚至不確定這是做到這一點的正確方法。有人可以告訴我最近的做法嗎?

這裏是我的代碼:

import React, {Component} from 'react' 
import 'bootstrap/dist/css/bootstrap.css'; 

export default class PriceTable extends Component { 
    constructor(props, context) { 
    super(props, context); 

    this.state = { 
     pid: this.props.pid || "12345", 
     name: this.props.name || "name", 
     prices: this.props.prices || [ 
     {count: 1, desc: 'one', price: 8.25}, 
     {count: 6, desc: 'six', price: 7.60}, 
     {count: 12, desc: 'twelve', price: 6.953} 
     ] 
    }; 

    this.setPid = this.setPid.bind(this); 
    this.setName = this.setName.bind(this); 
    this.setCount = this.setCount.bind(this, i); 
    this.setDesc = this.setDesc.bind(this, i); 
    this.setPrice = this.setPrice.bind(this, i); 
    this.logDebug = this.logDebug.bind(this); 
    } 

    setPid(e) { 
    this.setState({pid: e.target.value}) 
    } 

    setName(e) { 
    this.setState({name: e.target.value}) 
    } 

    setCount(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].count = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    setDesc(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].sec = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    setPrice(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].price = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    _renderPriceRow(price, i) { 
    return (
     <tr key={i}> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.count} onChange={this.setCount(this, i).bind(this, i)}/> 
     </td> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.desc} onChange={this.setDesc(this, i).bind(this, i)}/> 
     </td> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.price} onChange={this.setPrice(this, i).bind(this, i)}/> 
     </td> 
     </tr> 
    ); 
    } 

    render() { 
    return (
     <div className="row"> 
     ... 
     </div> 
    ); 
    } 
} 

這是錯誤...

PriceTable.jsx:21 Uncaught ReferenceError: i is not defined 
    at new PriceTable (PriceTable.jsx:21) 

回答

4

您不正確綁定功能

在你的構造函數,你不需要指定的說法,你只需要綁定像this.setDesc = this.setDesc.bind(this);

也在你onChange,當你想將參數傳遞給你用bind指定的參數,而不是作爲參數傳遞並再次綁定它們。

onChange={this.setDesc.bind(this, i)} 

你整個代碼看起來像

import React, {Component} from 'react' 
import 'bootstrap/dist/css/bootstrap.css'; 

export default class PriceTable extends Component { 
    constructor(props, context) { 
    super(props, context); 

    this.state = { 
     pid: this.props.pid || "12345", 
     name: this.props.name || "name", 
     prices: this.props.prices || [ 
     {count: 1, desc: 'one', price: 8.25}, 
     {count: 6, desc: 'six', price: 7.60}, 
     {count: 12, desc: 'twelve', price: 6.953} 
     ] 
    }; 

    this.setPid = this.setPid.bind(this); 
    this.setName = this.setName.bind(this); 
    this.setCount = this.setCount.bind(this); 
    this.setDesc = this.setDesc.bind(this); 
    this.setPrice = this.setPrice.bind(this); 
    this.logDebug = this.logDebug.bind(this); 
    this._renderPriceRow = this._renderPriceRow.bind(this); 
    } 

    setPid(e) { 
    this.setState({pid: e.target.value}) 
    } 

    setName(e) { 
    this.setState({name: e.target.value}) 
    } 

    setCount(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].count = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    setDesc(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].sec = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    setPrice(i, e) { 
    var newPrices = this.state.prices 
    newPrices[i].price = e.target.value 
    this.setState({prices: newPrices}) 
    } 

    _renderPriceRow(price, i) { 
    return (
     <tr key={i}> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.count} onChange={this.setCount.bind(this, i)}/> 
     </td> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.desc} onChange={this.setDesc.bind(this, i)}/> 
     </td> 
     <td > 
      <input type="text" className="form-control" defaultValue={price.price} onChange={this.setPrice.bind(this, i)}/> 
     </td> 
     </tr> 
    ); 
    } 

    render() { 
    return (
     <div className="row"> 
     ... 
     </div> 
    ); 
    } 
} 

你也可以利用Arrow functions傳遞參數,如

onChange={(e) => this.setDesc(e, i)} 
+0

這實際上與根本不綁定函數的效果相同。我得到以下錯誤:'''Uncaught TypeError:無法在_renderPriceRow中讀取未定義屬性'setCount''' –

+0

那是因爲您沒有綁定renderPriceRow函數。檢查更新 –

+0

您可以簡要解釋爲什麼我必須綁定該功能嗎?是因爲這個函數超出了實際類的範圍嗎?這在這裏看起來像是一個奇怪的樣板代碼。爲什麼它沒有像ES5那樣綁定? –

1

使用onChange方法是這樣的:

onChange={this.setCount.bind(this, i)} 
onChange={this.setDesc.bind(this, i)} 
onChange={this.setPrice.bind(this, i)} 

constructor刪除這些行:

this.setCount = this.setCount.bind(this, i); 
this.setDesc = this.setDesc.bind(this, i); 
this.setPrice = this.setPrice.bind(this, i); 

我們可以bindfunctionconstructor,在不需要額外的參數,如這些functions你的情況:

this.setPid = this.setPid.bind(this); 
this.setName = this.setName.bind(this); 
this.logDebug = this.logDebug.bind(this); 

但是,如果在任何function你想傳遞任何額外的參數,那麼你需要使用arrow functionbindfunction通過使用.bind(this, parameter)

注意

,你需要在這裏的變化是,你現在的樣子更新state值的另一件事,你永遠不應該發生變異狀態變量直接。當您將array分配給任何變量時,該變量將引用該array,表示對該變量所做的任何更改都會影響原始array

因此,您需要創建該變量的副本,然後對其進行更改並使用setState來更新值。

DOC

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

+0

好吧,我會做拷貝的東西。實際上,你建議刪除的行是我的天真的解決方案,以解決以前的錯誤:'''Uncaught TypeError:無法讀取_renderPriceRow undefined屬性'setCount'''' –

+0

不,不管我的建議會正常工作,我相信這一點,將提供一個工作代碼:) –

+0

becuas eyou沒有綁定'_renderPriceRow'函數。 –

相關問題