将多个参数传递给 React 中的事件处理程序

IT技术 reactjs twitter-bootstrap-3
2021-04-09 01:13:27

所以我试图让 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)
2个回答

您绑定的功能不正确

在你的构造函数中,你不需要指定参数,你只需要像这样绑定它 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>
    );
  }
}

您还可以使用箭头函数来传递参数,例如

onChange={(e) => this.setDesc(e,  i)}
您也需要绑定该函数,因为它this用作调用setCount函数的引用,并且this如果您不绑定它函数中的 where是指函数本身的上下文。很像绑定其他使用的函数setState
2021-05-25 01:13:27
这实际上与根本不绑定函数具有相同的效果。我收到以下错误:Uncaught TypeError: Cannot read property 'setCount' of undefined at _renderPriceRow
2021-06-01 01:13:27
您能否简要解释一下为什么我也必须绑定该功能?是不是因为函数超出了实际类的范围?这里的样板代码数量似乎很奇怪。为什么不像之前的 ES5 那样绑定?
2021-06-05 01:13:27
那是因为您还没有绑定 renderPriceRow 函数。检查更新
2021-06-21 01:13:27

使用这样的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 function或者bindfunction通过使用.bind(this, parameter)

注意

您需要在这里更改的另一件事是,您更新state值的方式,您永远不应该直接改变状态变量当您将 an 分配array给任何变量时,该变量将具有 that 的引用,这array意味着您对该变量所做的任何更改都会影响原始array.

因此,您需要创建该变量的副本,然后对其进行更改并用于setState更新值。

根据DOC

永远不要直接改变 this.state,因为之后调用 setState() 可能会替换你所做的改变。将 this.state 视为不可变的。

不,不是这样,我建议的任何内容都可以正常工作,我确信这一点,将提供一个有效的代码:)
2021-05-22 01:13:27
因为 eyou 没有绑定_renderPriceRow函数。
2021-05-26 01:13:27
在构造函数中写下这一行: this._renderPriceRow = this._renderPriceRow.bind(this);
2021-06-14 01:13:27
好的,我会做复制的东西。实际上,您建议删除的行是我修复先前错误的天真方法:Uncaught TypeError: Cannot read property 'setCount' of undefined at _renderPriceRow
2021-06-20 01:13:27