为了账号安全,请及时绑定邮箱和手机立即绑定

React,无法根据当前状态设置状态(状态落后一步)

React,无法根据当前状态设置状态(状态落后一步)

阿波罗的战车 2023-12-14 15:34:02
我完全迷失了 React async setState :(代码沙箱这就是我想要实现的目标:当我单击操作符按钮(App.js 第 81-98 行)时,我采用 current(new\updated) state.input,用我的函数“格式化”它fixInput(App.js 第 7-22 行,它接受state.input和 event.target.textContent,返回新字符串),并将结果设置为新state.input值。//Display.jsconst Display = (props) => {  //on equals  click  show  the  output ,  if  input continues  , show input, change showoutput  let { input, output, showInput } = props;  return (    <div id="display" className="display_font">      {showInput ? input : output}    </div>  );};//Keypad.jsconst Keypad = (props) => {  return (    <div id="keypad">      <button id="clear" onClick={props.handleCeClick}>        CE      </button>      <button id="seven" onClick={props.handleNumClick}>        7      </button>      <button id="eight" onClick={props.handleNumClick}>        8      </button>      <button id="nine" onClick={props.handleNumClick}>        9      </button>      <button id="add" onClick={props.handleOperClick}>        +      </button>      <button id="four" onClick={props.handleNumClick}>        4      </button>      <button id="five" onClick={props.handleNumClick}>        5      </button>      <button id="six" onClick={props.handleNumClick}>        6      </button>      <button id="subtract" onClick={props.handleOperClick}>        -      </button>      <button id="one" onClick={props.handleNumClick}>        1      </button>      <button id="two" onClick={props.handleNumClick}>        2      </button>      <button id="three" onClick={props.handleNumClick}>        3      </button>      <button id="multiply" onClick={props.handleOperClick}>        *      </button>    </div>  );};React setState 是异步的,并且不会立即更新,因此我只能访问以前的 state.input,我可以从 setState 回调记录到控制台当前状态,并且我需要设置一个新状态,这是我无法从回调中执行的。我无法访问当前状态,这就是为什么我的fixInput功能无法正常工作(按数字和重复运算符,例如4++,预计只允许添加运算符*-和的两种组合/-我确实尝试过用我能想到的各种方式来改变事情。我的方法有什么问题吗?我的结构可以做到这一点吗?
查看完整描述

2 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

https://img1.sycdn.imooc.com/657ab0160001dda603140206.jpg

对我来说一切似乎都很好,只需根据给定的规范清理输入方程,所有测试用例都将得到满足。


对handleEqualClick()功能进行以下更改:


  handleEqualsClick = () => {

    const { input } = this.state;

    //todo ? if the last char is oper, delete it

    // console.log(input);

    let eq = [];

    for (let ch of [...input]) {

      if (!eq.length) {

        eq.push(ch);

      } else {

        if (ch === "-") {

          eq.push("-");

        } else if ("+-*/".includes(ch) && "+-*/".includes(eq[eq.length - 1])) {

          while ("+-*/".includes(ch) && "+-*/".includes(eq[eq.length - 1])) {

            eq.pop();

          }

          eq.push(ch);

        } else {

          eq.push(ch);

        }

      }

    }

    let sanitizedInput = eq.join("");

    console.log(sanitizedInput);

    let result = +eval(sanitizedInput).toFixed(7).toString();

    console.log("result:", result);


    if (result.length > 11) {

      result = result.slice(0, 11);

    }

    this.setState((state) => ({

      showInput: false,

      output: result,

      input: result //test14

    }));

  };

代码沙箱链接


查看完整回答
反对 回复 2023-12-14
?
智慧大石

TA贡献1946条经验 获得超3个赞

一些说明:我想要 1) 通过测试#13,2) 在显示上看到正确的字符

功能上有错误fixInput,我this.state.input在需要更新版本时进行了测试,该版本是this.state.input + value.

function fixInput(inputStr, currentOp) {

    const lastTwoOp = /([+\-*/]{2})$/;

    const lastThreeOp = /([+\-*/]{3})$/;

    const allowTwo = /(\*|\/)-/;


    const toTest = inputStr + currentOp; //<= 


    if (lastTwoOp.test(toTest) && !allowTwo.test(toTest)) {

        inputStr = inputStr.slice(0, -1) + currentOp;

    } else if (lastThreeOp.test(toTest)) {

        inputStr = inputStr.slice(0, -2) + currentOp;

    } else {

        inputStr += currentOp;

    }

    return inputStr;

}


查看完整回答
反对 回复 2023-12-14
  • 2 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信