繁体   English   中英

为什么我必须单击两次才能触发事件?

[英]Why do I have to click twice for an event to fire in react?

抱歉这个问题很简单,我对 React 很陌生。 我用两个输入字段和按钮构建了一个计算器来处理不同的计算。 现在,我将它改造成一个功能更齐全的计算器,带有一个完整的键盘。 在下面的代码中,我很确定我编写“onClick”function 的方式是问题所在,但我不确定应该如何编写。 (示例中的大部分代码都与初始项目有关,与这个问题无关,我只是想包含整个组件以便更好地衡量。)

当我单击“1”按钮时,它第一次控制台记录 1,但页面顶部的 1 直到第二次单击才会显示。 我在这里发生了什么,直到我第二次单击“1”按钮才允许显示在顶部?

首次点击:首次点击后的应用 1

第二次点击:第二次点击后的应用 1

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.setNum1 = this.setNum1.bind(this);
    this.setNum2 = this.setNum2.bind(this);
    this.add = this.add.bind(this);
    this.subtract = this.subtract.bind(this);
    this.multiply = this.multiply.bind(this);
    this.divide = this.divide.bind(this);
    this.clear = this.clear.bind(this);
    this.buttonPressed = this.buttonPressed.bind(this);

    this.state = {
      pressed: "",
      result: "",
      num1: "",
      num2: "",
    };
  }

  buttonPressed(e) {
    e.preventDefault();
    const pressed = e.target.name;
    const result = this.state.pressed;
    this.setState({ pressed });
    this.setState({ result });
    console.log(e.target.name);
  }

  setNum1(e) {
    const num1 = e.target.value ? parseInt(e.target.value) : "";
    this.setState({ num1 });
  }

  setNum2(e) {
    const num2 = e.target.value ? parseInt(e.target.value) : "";
    this.setState({ num2 });
  }

  add(e) {
    e.preventDefault();
    const result = this.state.num1 + this.state.num2;
    this.setState({ result });
  }

  subtract(e) {
    e.preventDefault();
    const result = this.state.num1 - this.state.num2;
    this.setState({ result });
  }

  multiply(e) {
    e.preventDefault();
    const result = this.state.num1 * this.state.num2;
    this.setState({ result });
  }

  divide(e) {
    e.preventDefault();
    const result = this.state.num1 / this.state.num2;
    this.setState({ result });
  }

  clear(e) {
    e.preventDefault();
    this.setState({ num1: "", num2: "", result: 0 });
  }

  render() {
    const { num1, num2, result } = this.state;
    return (
      <div>
        <h1>{this.state.result}</h1>
        <input onChange={this.setNum1} value={num1}></input>
        <input onChange={this.setNum2} value={num2}></input>
        <br />
        <button name="1" onClick={this.buttonPressed}>
          1
        </button>
        <button onClick={this.add}>+</button>
        <button onClick={this.subtract}>-</button>
        <button onClick={this.multiply}>x</button>
        <button onClick={this.divide}>/</button>
        <button onClick={this.clear}>clear</button>
      </div>
    );
  }
}

export default Calculator;

如果有人可以帮助我了解我需要做些什么来解决这种情况,我将不胜感激!

这里的问题在于

 buttonPressed(e) {
    e.preventDefault();
    // here e.target.name is 1 so value in const pressed becomes 1
    const pressed = e.target.name;
    // currently this.state.pressed is "" so result becomes "" if you want to show
    // first number as result use const result = e.target.name
    const result = this.state.pressed;
    this.setState({ pressed });
    this.setState({ result });
    console.log(e.target.name);
  }

您将结果设置为 this.state.pressed ,它在第一次为空,因此它将结果设置为空字符串,但在第二次设置为 this.state.pressed 为 1,因此它将结果设置为 1,因此在第二次点击时显示

推理:

  • 阻止导致问题的

    buttonPressed(e) { e.preventDefault(); const pressed = e.target.name; const result = this.state.pressed; this.setState({ pressed }); this.setState({ result }); console.log(e.target.name); }
  • Reason: setState is going to take a while to update the state object values (ie) setState does not update state object immediately as its async in nature.

  • 参考: 为什么 React setState/useState 不会立即更新 - 博客

下面列出了此问题的可能解决方案

案例A:设置'结果' state object 基于'按下' state ZA8CFDE6331BD59EB2ACZ66B86

  • Note: setting state of other object once target object state change was set using call back function

  • 目标:设置“结果”state object 仅在“按下”state ZA8CFDE6331BD59EB2AC96B891 之后设置

  • 实现:一旦“按下”state 被设置,我们执行一个回调 function 来设置“结果”state ZA8CFDE6F63311

  • 句法:

    this.setState(setTargetStateObject, function() { // 执行 setTargetStateObject 完成后必须执行的操作 });

  • 解决方案:

     buttonPressed(e) { e.preventDefault(); const pressed = e.target.name; this.setState({ pressed }, function() { this.setState({ result: this.state.pressed }); }); }

案例 B:根据传递的 'e' arg 值设置结果 state object

  • 解决方案:

     buttonPressed(e) { e.preventDefault(); const pressed = e.target.name; // const result = this.state.pressed; // directly assign the 'e' arg value to the result const variable const result = pressed; // 'result' state object is not dependent on 'pressed' state object this.setState({ pressed }); this.setState({ result }); console.log(e.target.name); }

注意:我建议你使用函数式组件,因为你可以拥有更少行数的干净代码,使用 React 团队新引入的钩子,更容易编写测试,最重要的是性能也是如此。

为您创建了这个沙箱计算器 pgm - class 与功能性反应组件- 您可以查看您的相同程序如何在 class 与功能性组件中实现。

参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM