将多个参数传递给 React 中的事件处理程序
Posted
技术标签:
【中文标题】将多个参数传递给 React 中的事件处理程序【英文标题】:Pass multiple parameters to event handlers in React 【发布时间】:2017-08-26 14:09:46 【问题描述】:所以我试图让 react 使用 ES6 语法。在 ES5 中,我有 setInitialState 没有使用函数绑定语法的构造函数。我有一个任意价格列表,我希望在输入元素更改时更改状态。但正确的价格必须改变。
我什至不太确定这是正确的做法。有人可以告诉我最近应该做的方式吗?
这是我的代码:
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)
【问题讨论】:
【参考方案1】:你绑定的函数不正确
在你的构造函数中你不需要指定参数,你只需要像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)
【讨论】:
这实际上与完全不绑定函数具有相同的效果。我收到以下错误:Uncaught TypeError: Cannot read property 'setCount' of undefined at _renderPriceRow
那是因为你没有绑定 renderPriceRow 函数。检查更新
你能简单解释一下为什么我也要绑定那个函数吗?是因为函数超出了实际类的范围吗?这似乎是一个奇怪的样板代码。为什么不像之前的 ES5 那样绑定?
您还需要绑定该函数,因为它使用this
作为调用setCount
函数的引用,并且函数中的this
指的是函数本身的上下文,如果您不这样做的话不要绑定它。很像绑定其他使用 setState
的函数【参考方案2】:
像这样使用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);
我们可以在constructor
中使用bind
function
,其中不需要额外的参数,例如您的这些functions
:
this.setPid = this.setPid.bind(this);
this.setName = this.setName.bind(this);
this.logDebug = this.logDebug.bind(this);
但是,如果在任何function
中你想传递任何额外的参数,那么你需要使用arrow function
或bind
,通过function
使用.bind(this, parameter)
。
注意:
您需要在此处更改的另一件事是,您更新state
值的方式,您不应该直接改变状态变量。当您将array
分配给任何变量时,该变量将具有该array
的引用,这意味着您对该变量所做的任何更改都会影响原始array
。
因此,您需要创建该变量的副本,然后对其进行更改并使用 setState
更新值。
根据DOC:
永远不要直接改变 this.state,因为之后调用 setState() 可能 替换您所做的突变。把 this.state 当作是 不可变。
【讨论】:
好的,我会做复制的。实际上,您建议删除的行是我修复先前错误的天真方法:Uncaught TypeError: Cannot read property 'setCount' of undefined at _renderPriceRow
不,不是这样,无论我建议什么都能正常工作,我确信,将提供一个工作代码:)
因为你没有绑定_renderPriceRow
函数。
在构造函数中写入这一行:this._renderPriceRow = this._renderPriceRow.bind(this);
以上是关于将多个参数传递给 React 中的事件处理程序的主要内容,如果未能解决你的问题,请参考以下文章