Javascript 反应,可以';t根据当前状态设置状态(状态落后一步)
我完全无法使用React async setState:( 以下是我试图实现的目标:当我单击operator按钮(App.js第81-98行)时,我获取当前(新建\更新)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})$/
状态。输入
,用我的固定输入
函数“格式化”它(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;
}