首页 > 解决方案 > 反应/无法重置当前状态

问题描述

我正在用 React 制作一个计算器应用程序。到目前为止,每个操作员都工作得很好。但是,当我单击“=”按钮并获得结果,然后单击另一个按钮时,将无法正确添加数字。

我知道有很多冗余代码,但现在我关注的问题是我得到结果后无法重置数字。

class App extends React.Component {

    state = {
        num1: [],
        num2: [],
        operator: null,
        result: null
    };

    currentNumber = (digit) => {

        if(this.state.operator===null) {

            let newNum1 = [...this.state.num1, digit];
            console.log("num1 FIRST", newNum1.join(''));
            this.setState({num1: newNum1.join('')})
            console.log("num1 AFTER", newNum1.join(''));
        }

        if(this.state.num1!==[] && this.state.operator!=null) {
            this.setState({num2: []})
            let newNum2 = [...this.state.num2, digit];
            console.log("num2 FIRST", newNum2.join(''));         
            this.setState({num2: newNum2.join('')})
            console.log("num2 AFTER", newNum2.join(''));
        }
    }

    getResult = () => {
        if(this.state.operator==="+") {
            this.setState({operator: "+"});
            let newNumber = parseInt(this.state.num1) + parseInt(this.state.num2);
            this.setState({result: newNumber})      
        } else if(this.state.operator==="-") {
            this.setState({operator: "-"});
            let newNumber = parseInt(this.state.num1) - parseInt(this.state.num2);
            this.setState({result: newNumber})      
        } else if(this.state.operator==="x") {
            this.setState({operator: "x"});
            let newNumber = parseInt(this.state.num1) * parseInt(this.state.num2);
            this.setState({result: newNumber})      
        } else if(this.state.operator==="÷") {
            this.setState({operator: "÷"});
            let newNumber = (parseInt(this.state.num1)) / (parseInt(this.state.num2));
            this.setState({result: newNumber.toFixed(2)})      
        }
        console.log("Current operator", this.state.operator);
    }

    clearDigit = () => {
        this.setState({num1: [], num2: [], operator: null, result: null});
    }

    displayOperator = (sign) => {
        this.setState({operator: sign});
    }

    render() {
        return (
            <div className="calculator_container">
                    <Screen 
                        num1 = {this.state.num1}
                        num2 = {this.state.num2}
                        operator = {this.state.operator}
                        displayNumber = {this.state.result}
                    />

                <Button 
                    onClick = {this.currentNumber}
                    getResult = {this.getResult}
                    clearButtonClick = {this.clearDigit}
                    showOperator = {this.displayOperator}
                />
            </div>
        );
    }
}
class Button extends React.Component {

    render() {
        return (
            <ul>
                <li><button data-number="1" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>1</button></li>
                <li><button data-number="2" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>2</button></li>
                <li><button data-number="3" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>3</button></li>
                <li><button data-number="x" onClick={event => this.props.showOperator(event.target.getAttribute('data-number'))}>×</button></li>
                <li><button data-number="4" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>4</button></li>
                <li><button data-number="5" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>5</button></li>
                <li><button data-number="6" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>6</button></li>
                <li><button data-number="÷" onClick={event => this.props.showOperator(event.target.getAttribute('data-number'))}>÷</button></li>
                <li><button data-number="7" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>7</button></li>
                <li><button data-number="8" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>8</button></li>
                <li><button data-number="9" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>9</button></li>
                <li><button data-number="+" onClick={event => this.props.showOperator(event.target.getAttribute('data-number'))}>+</button></li>
                <li><button data-number="0" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>0</button></li>
                <li><button data-number="AC" onClick={this.props.clearButtonClick}>AC</button></li>
                <li><button data-number="=" onClick={this.props.getResult}>=</button></li>
                <li><button data-number="-" onClick={event => this.props.showOperator(event.target.getAttribute('data-number'))}>-</button></li>
            </ul>
        );
    }
}
class Screen extends React.Component {

    displayAddedNumber = () => {
        this.props.displayNumber();
    }

    render() {
        return (
            <div className="display">
                {this.props.num1} {this.props.operator} {this.props.num2}<br />
            <span>{this.props.displayNumber}</span>
            </div>
        );
    }
}

标签: reactjscalculator

解决方案


从我看到你有几个选择:

  1. 结果后重置(在末尾getResult()):
this.setState({num1: [], num2: [], operator: null});
  1. displayOperator()在结果后的第一个数字上重置(在和之上currentNumber()):
if(this.state.result){
  this.clearDigit();
}

然后切换到使用 setState 中的函数而不是对象,因为您使用的是旧状态。


还:

1:

/*...*/
if(this.state.operator==="+") {
  this.setState({operator: "+"}); // <-- you dont need this, you just aserted it's '+'
  let newNumber = parseInt(this.state.num1) + parseInt(this.state.num2);
  this.setState({result: newNumber})      
}
/*...*/

2:不要在函数执行中创建多个 setState,这不仅会导致性能不佳,而且您在这里的代码也很脏,您应该查看策略模式 :)

3:你不能这样比较——因为你在比较对象引用,所以它不起作用

this.state.num1 !== []

你要么想要this.state.num1.length === 0Array.isArray(this.state.num1)(或两者)


推荐阅读