Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应,可以';t根据当前状态设置状态(状态落后一步)_Javascript_Reactjs_Setstate - Fatal编程技术网

Javascript 反应,可以';t根据当前状态设置状态(状态落后一步)

Javascript 反应,可以';t根据当前状态设置状态(状态落后一步),javascript,reactjs,setstate,Javascript,Reactjs,Setstate,我完全无法使用React async setState:( 以下是我试图实现的目标:当我单击operator按钮(App.js第81-98行)时,我获取当前(新建\更新)状态。输入,用我的固定输入函数“格式化”它(App.js第7-22行,它获取状态。输入和事件。目标。文本内容,返回新字符串),并将结果设置为新的状态。输入值 //App.js function fixInput(inputStr, currentOp) { const lastTwoOp = /([+\-*/]{2})$/

我完全无法使用React async setState:(

以下是我试图实现的目标:当我单击operator按钮(App.js第81-98行)时,我获取当前(新建\更新)
状态。输入
,用我的
固定输入
函数“格式化”它(App.js第7-22行,它获取
状态。输入
事件。目标。文本内容
,返回新字符串),并将结果设置为新的
状态。输入

//App.js
function fixInput(inputStr, currentOp) {
  const lastTwoOp = /([+\-*/]{2})$/;
  const lastThreeOp = /([+\-*/]{3})$/; //
  const allowTwo = /(\*|\/)-/; //don't replace *- and /-
  //this  is not  working correctly
  if (lastTwoOp.test(inputStr) && !allowTwo.test(inputStr)) {
    // if there are 2 operators and those are not the allowed combinations, replace  them with the last operator
    inputStr = inputStr.slice(0, -2) + currentOp;
  } else if (lastThreeOp.test(inputStr)) {
    // if there are 3 operators, replace  them with the last operator
    inputStr = inputStr.slice(0, -3) + currentOp;
  } else {
    inputStr += currentOp;
  }
  return inputStr;
}

const init = () => ({
  input: "",
  output: 0,
  showInput: false,
  decimal: false,
  clickedOp: ""
});

export default class App extends Component {
  state = init();

  // HANDLERS
  handleCeClick = () => {
    this.setState(init);
  };

  handleNumClick = (e) => {
    const { input } = this.state;
    const value = e.target.textContent;
    if (e.target.id === "zero" && +input === 0) {
      //if there's 0 in input and 0 is clicked, do nothing
      e.preventDefault();
    } else {
      //add number to input,showinput, reset operators number
      this.setState((state) => ({
        input: input + value,
        showInput: true,
        opnum: 0
      }));
    }
  };

  handleDecClick = (e) => {
    const value = e.target.textContent;
    const { input, decimal } = this.state;
    if (decimal === true) {
      //if there's decimal in the input, do nothing
      e.preventDefault();
    } else {
      //add decimal to the input
      if (!input) {
        this.setState({
          input: "0."
        });
      } else {
        this.setState({
          input: input + value
        });
      }
      //default behavior: set decimal to true and show the input
      this.setState({
        decimal: true,
        showInput: true
      });
    }
  };

  handleOperClick = (e) => {
    const value = e.target.textContent;
    const fixedInput = fixInput(this.state.input, value);

    this.setState(
      (state, props) => {
        return {
          input: fixedInput,
          decimal: false,
          showInput: true,
          latestOper: value
        };
      },
      () => {
        console.log(this.state.input); //current state here  i want to  use this value in fixInput function and  set as  new input state:/
      }
    );
  };

  handleEqualsClick = () => {
    const { input } = this.state;
    //todo ? if the last char is oper, delete it
    // console.log(input);
    let result = +eval(input).toFixed(7).toString();

    if (result.length > 11) {
      result = result.slice(0, 11);
    }
    this.setState((state) => ({
      showInput: false,
      output: result,
      input: result //test14
    }));
  };

  render() {
    const handlers = {
      handleCeClick: this.handleCeClick,
      handleNumClick: this.handleNumClick,
      handleOperClick: this.handleOperClick,
      handleEqualsClick: this.handleEqualsClick,
      handleDecClick: this.handleDecClick,
      handleInput: this.handleInput
    };
    const { input, output, showInput } = this.state;
    return (
      <>
        <Display output={output} input={input} showInput={showInput} />
        <Keypad {...handlers} />
      </>
    );
  }
}
//App.js
函数fixInput(inputStr,currentOp){
常量lastTwoOp=/([+\-*/]{2})$/;
常量lastThreeOp=/([+\-*/]{3})$///
const allowTwo=/(\*\/)-///不替换*-和/-
//这工作不正常
if(lastTwoOp.test(inputStr)和&!allowTwo.test(inputStr)){
//如果有2个运算符,且这些运算符不是允许的组合,则用最后一个运算符替换它们
inputStr=inputStr.slice(0,-2)+currentOp;
}else if(最后三次操作测试(inputStr)){
//如果有3个操作员,则将其替换为最后一个操作员
inputStr=inputStr.slice(0,-3)+currentOp;
}否则{
inputStr+=currentOp;
}
返回inputStr;
}
常量init=()=>({
输入:“,
输出:0,
showInput:false,
小数点:false,
clickedOp:“
});
导出默认类应用程序扩展组件{
state=init();
//处理者
HandleClick=()=>{
这个.setState(init);
};
handleNumClick=(e)=>{
const{input}=this.state;
常量值=e.target.textContent;
如果(e.target.id==“零”&&&+input==0){
//如果输入中有0,并且单击了0,则不执行任何操作
e、 预防默认值();
}否则{
//将编号添加到输入、显示输入、重置操作员编号
this.setState((状态)=>({
输入:输入+值,
showInput:true,
操作数:0
}));
}
};
HandleDeclick=(e)=>{
常量值=e.target.textContent;
const{input,decimal}=this.state;
如果(十进制===真){
//如果输入中有小数,则不执行任何操作
e、 预防默认值();
}否则{
//向输入中添加小数
如果(!输入){
这是我的国家({
输入:“0。”
});
}否则{
这是我的国家({
输入:输入+值
});
}
//默认行为:将decimal设置为true并显示输入
这是我的国家({
是的,
showInput:true
});
}
};
handleOperClick=(e)=>{
常量值=e.target.textContent;
const fixedInput=fixInput(this.state.input,value);
这是我的国家(
(状态、道具)=>{
返回{
输入:fixedInput,
小数点:false,
showInput:true,
迟到者:价值
};
},
() => {
console.log(this.state.input);//此处的当前状态我想在fixInput函数中使用此值并设置为新的输入状态:/
}
);
};
handleEqualsClick=()=>{
const{input}=this.state;
//todo?如果最后一个字符有效,请将其删除
//控制台日志(输入);
让结果=+eval(输入).toFixed(7.toString();
如果(结果长度>11){
结果=结果切片(0,11);
}
this.setState((状态)=>({
showInput:false,
输出:结果,
输入:结果//测试14
}));
};
render(){
常量处理程序={
这个,
handleNumClick:this.handleNumClick,
handleOperClick:这个,handleOperClick,
handleEqualsClick:this.handleEqualsClick,
handledeclick:this.handledeclick,
handleInput:this.handleInput
};
const{input,output,showInput}=this.state;
返回(
);
}
}
//Display.js
常量显示=(道具)=>{
//在equals上单击显示输出,如果输入继续,则显示输入,更改显示输出
设{input,output,showInput}=props;
返回(
{showInput?输入:输出}
);
};
//Keypad.js
常量键盘=(道具)=>{
返回(
总工程师
7.
8.
9
+
4.
5.
6.
-
1.
2.
3.
*
0
.
=
/
);
};
React setState是异步的,它不会立即更新,因此我只能访问以前的状态。输入,我可以从setState回调记录到控制台当前状态,并且我需要设置一个新状态,这是我无法从回调中执行的。我无法访问当前状态,这就是为什么我的
fixInput
函数无法正常工作的原因(按数字和重复运算符,例如
4++
,预计只允许添加两种运算符组合
*-
/-

我确实试着用我能想到的每一种方式来移动东西

我的方法有什么问题?我现有的结构是否可能出现这种情况?

在我看来一切都很好,只要根据给定的规范清理输入方程,所有的测试用例都将得到满足

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
    }));
  };

一些澄清:我想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;
}
函数fixInput(inputStr,currentOp){ 常量lastTwoOp=/([+\-*/]{2})$/; 常量lastThreeOp=/([+\-*/]{3})$/; 常量allowTwo=/(\*\/)-/;
const toTest=inputStr+currentOp;//我不确定我是否了解这里的问题。是否要传递cu
  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
    }));
  };
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;
}