为什么更改状态值不会触发REACT中输入元素的onChange

时间:2019-11-21 23:04:41

标签: javascript reactjs

我有输入,其值由按钮元素更改。我需要一种方法来调用该输入的onChange。更改值后,我必须进行一些验证。

我在StackOverflow上找到了一些答案,但他们使用的是调度程序,他们没有正确解释或我没有正确使用它。

但是状态更新时不会调用onChange。这就是我现在所拥有的

<div className="input-group">
  <input type="text" className="form-control quantity-field text-center" onChange={(e) => this.handleChange(e)} value={this.state.quantity}/>
  <button onClick={(e) => this.handleIncDec(e)}>+</button>
</div>
  handleIncDec = (e) => {
    e.preventDefault()

    this.setState({
      quantity: this.state.quantity += 1
    })
  }

handleChange = e => {
    console.log(e.target.value);

    const re = /^[0-9\b]+$/;
    if (e.target.value === '' || re.test(e.target.value)) {
      this.setState({
        quantity: e.target.value
      })
    }
  };

输入的值应该正确更新,但是除非我直接在该输入中而不是通过按钮更新值,否则永远不会调用onChange。

如果您需要其他任何信息告诉我,我会提供。

1 个答案:

答案 0 :(得分:2)

默认情况下,仅在用户输入上调用onChange事件。在大多数情况下,您可以通过在React中使用ComponentDidUpdate之类的生命周期方法来避免以编程方式触发onChange事件。在您的示例中,对我来说,您似乎只需要验证来自两个不同来源的输入,因此,我建议采用一种更简单的实现。

您是否可以创建验证功能,而不是同时在handleChangehandleInDec上使用?

您还应避免使用this.setState({ quantity: this.state.quantity += 1})根据先前状态更新状态,因为不能保证总是会更新状态(请记住,setState是异步的)。而是使用guarantees updated state-values

setState返回的值

class Test extends React.Component {
  constructor() {
    super();

    this.state = {
      quantity: 0
    };
  }

  handleIncDec = e => {
    e.preventDefault();

    this.setState(prevState => {
      var newQuantity = prevState.quantity + 1;
      if (this.isValidInputData(newQuantity)) {
        return {
          quantity: newQuantity
        };
      }
    });
  };

  handleChange = e => {
    if (this.isValidInputData(e.target.value)) {
      this.setState({
        quantity: e.target.value
      });
    }
  };

  isValidInputData = newQuantity => {
    const re = /^[0-9\b]+$/;
    return newQuantity === "" || re.test(newQuantity);
  };

  render() {
    return (
      <div className="input-group">
        <input
          type="text"
          className="form-control quantity-field text-center"
          onChange={this.handleChange}
          value={this.state.quantity}
        />
        <button onClick={this.handleIncDec}>+</button>
      </div>
    );
  }
}

ReactDOM.render(<Test />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>