reactjs - Pase múltiples parámetros a controladores de eventos en React
twitter-bootstrap-3 (2)
Estás vinculando las funciones incorrectamente
En su constructor no necesita especificar el argumento, solo necesita vincularlo como
this.setDesc = this.setDesc.bind(this);
También en su onChange, cuando desea pasar parámetros a la función, debe especificarla con bind y no pasar como argumentos y volver a vincularlos.
onChange={this.setDesc.bind(this, i)}
Tu código completo se verá como
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>
);
}
}
También puede utilizar las funciones de flecha para pasar parámetros como
onChange={(e) => this.setDesc(e, i)}
Así que estoy tratando de hacer que reaccionar funcione con la sintaxis de ES6. En ES5 tenía setInitialState sin un constructor que funcionara con la sintaxis de enlace de funciones. Tengo una lista de precios que es arbitraria y quiero que el estado cambie cuando se cambia el elemento de entrada. Pero el precio correcto tiene que ser cambiado.
Ni siquiera estoy seguro de que esta sea la forma correcta de hacerlo. ¿Puede alguien decirme la forma más reciente en que esto debería hacerse?
Aquí está mi código:
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>
);
}
}
Y este es el error ...
PriceTable.jsx:21 Uncaught ReferenceError: i is not defined
at new PriceTable (PriceTable.jsx:21)
Use el método
onChange
esta manera:
onChange={this.setCount.bind(this, i)}
onChange={this.setDesc.bind(this, i)}
onChange={this.setPrice.bind(this, i)}
Elimine estas líneas del
constructor
:
this.setCount = this.setCount.bind(this, i);
this.setDesc = this.setDesc.bind(this, i);
this.setPrice = this.setPrice.bind(this, i);
Podemos
bind
la
function
en el
constructor
, donde no se requiere ningún parámetro adicional, como estas
functions
en su caso:
this.setPid = this.setPid.bind(this);
this.setName = this.setName.bind(this);
this.logDebug = this.logDebug.bind(this);
Pero si en cualquier
function
desea pasar algún parámetro adicional, debe usar la
arrow function
o
bind
esa
function
utilizando
.bind(this, parameter)
.
Nota :
Otra cosa que debe cambiar aquí es la forma en que actualiza los valores de
state
. Nunca debe
mutar la variable de estado directamente
.
Cuando asigna una
array
a cualquier variable, esa variable tendrá la referencia de esa
array
, lo que significa que cualquier cambio que haga a esa variable afectará a la
array
original.
Por lo tanto, debe crear una copia de esa variable y luego hacer los cambios y usar
setState
para actualizar los valores.
Según DOC :
Nunca mutes this.state directamente, ya que llamar a setState () luego puede reemplazar la mutación que hiciste. Trate este estado como si fuera inmutable.