Реагировать приложение не обновляет this.state должным образом - PullRequest
0 голосов
/ 24 апреля 2018

В настоящее время я усиленно работаю над получением своего полного стека и решил расширить свои знания о JavaScript. Это решение в конечном итоге привело меня к React, но я - как уже упоминалось - нуб в этой библиотеке. Но это только означает, что мне нужно больше работать с этой технологией, чтобы прогрессировать в плане этих знаний.

Актуальные проблемы, с которыми я сталкиваюсь, на первый взгляд кажутся очень простыми; Видимо мое приложение реакции не обновляет this.state должным образом. Мне известно о том, что метод setState в React является асинхронным, поэтому я запускаю другие пользовательские методы при запуске встроенного второго обратного вызова setState (). Эта техника, очевидно, не самая лучшая, поскольку она не работает, как планировалось.

Мое приложение о простом калькуляторе с основными математическими операторами. Я хочу реализовать функцию, которая отслеживает потенциальные результаты заданных выражений в режиме реального времени под «входом», но мой подход не работает, хотя я думаю, что он не слишком далек от реального решения. Правильная функция запускается в нужное время, но как this.state.result, так и this.state.resultExpression, по-видимому, нет, потому что они не отображаются в отображаемых полях. Моя функция updateDigit () работает, как и планировалось, но когда дело доходит до отображения результата после нажатия кнопки «равно», буквально ничего не отображается - даже весь введенный ввод пропал.

Вот мой код:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './calc.css';

const showHistory = false;
const decimalPlace = 3;

const operatorSet = ["+", "-", '*', '/', '%'];

class Calculator extends Component {

    constructor(props) {
        super(props);
        this.recentResult == false;
        this.state = {
            output: '0',
            preview: '',
            history: [],
            result: '',
            resultExpression: ''
        };
        this.updateDigit = this.updateDigit.bind(this);
        this.updatePreview = this.updatePreview.bind(this);
        this.clearOutput = this.clearOutput.bind(this);
        this.getResult = this.getResult.bind(this);
        this.showResult = this.showResult.bind(this);
    }

    render() {
        return (
            <div className="calculator">
                <div className="comp5">
                    <div className="output">{this.state.output}</div>
                    <div className="preview">{this.state.getResult}</div>
                </div>
                <div className="comp4">
                    <div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>(</a></div>
                    <div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>)</a></div>
                    <div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>%</a></div>
                    <div className="button_div button_control">
                        <a href="#" draggable="false" onClick={this.updateDigit}>/</a>
                    </div>
                </div>
                <div className="comp3">
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>7</a></div>
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>8</a></div>
                    <div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>9</a></div>
                    <div className="button_min button_control">
                        <a href="#" draggable="false" onClick={this.updateDigit}>*</a>
                    </div>
                </div>
                <div className="comp2">
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>4</a></div>
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>5</a></div>
                    <div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>6</a></div>
                    <div className="button_plus button_control">
                        <a href="#" draggable="false" onClick={this.updateDigit}>-</a>
                    </div>
                </div>
                <div className="comp1">
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>1</a></div>
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>2</a></div>
                    <div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>3</a></div>
                    <div className="button_plus button_control">
                        <a href="#" draggable="false" onClick={this.updateDigit}>+</a>
                    </div>
                </div>
                <div className="comp0">
                    <div className="numpad clear"><a href="#" draggable="false" onClick={this.clearOutput}>C</a></div>
                    <div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>0</a></div>
                    <div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>.</a></div>
                    <div className="button_res button_control">
                        <a href="#" draggable="false" onClick={this.showResult}>=</a>
                    </div>
                </div>
                <History expressions={this.state.history} />
            </div>
        );
    }


    updateDigit(event) {
        event.preventDefault;
        if (this.recentResult == true || this.state.output == "0") {
            this.recentResult = false;
            this.setState({ output: '' });
        }
        const newDigit = {
            digit: event.target.innerHTML,
            id: Date.now()
        };
        this.setState(prevState => ({
            output: prevState.output.concat(newDigit.digit)
        }), this.updatePreview());
    }


    updatePreview(event) {
        if (this.state.output == "0") {
            this.setState({ preview: '' });
        }
        let checkPreviewable = (output) => {
            var charactersAfterOperator = false;
            for (var i = 0; i < operatorSet.length; i++) {
                var currentOperator = operatorSet[i];
                let operatorLocation = output.indexOf(currentOperator)
                if (operatorLocation < output.length && operatorLocation > 0) {
                    return true;
                } else {
                    return false;
                }
            }
        };
        let previewable = checkPreviewable(this.state.output);
        if (previewable === true) {
            let resultExpression = this.state.resultExpression;
            this.setState({ preview: this.state.result });
        } else {
            this.setState({ preview: '' });
        }
    }


    clearOutput(event) {
        event.preventDefault();
        this.setState({ output: '0' });
    }


    getResult(event) {
        var result = eval(this.state.output).toFixed(decimalPlace);
        var resultExpression = this.state.output + "=" + result;

        this.setState({
            result: result,
            resultExpression: resultExpression
        }, this.updatePreview());
    }


    showResult(event) {
        this.getResult();
        let result = this.state.result;
        let resultExpression = this.state.resultExpression;
        this.setState({ output: result });
        this.setState(prevState => ({
            history: prevState.history.concat(resultExpression)
        }));
        this.recentResult = true;
    }

}

export default Calculator;



class History extends React.Component {
    render() {
        if (showHistory === false) return false;
        return (
            <ul>
                {this.props.expressions.map(expression => (
                    <li>{expression}</li>
                ))}
            </ul>
        )
    }
}

Есть ли у вас какие-либо идеи, почему это происходит, действительно ли вы сталкивались с подобной ситуацией или вы могли бы предложить альтернативу / решение?

Заранее спасибо за любую помощь, J0nny

1 Ответ

0 голосов
/ 24 апреля 2018

Я наблюдал за вашим кодом, и я вижу, что у вас много функций setState.

Каждый раз, когда вы вызываете setstate, ваш компонент отображается снова, и ваш код не завершает текущий поток.

Если вам нужно выполнить что-либо после функции setstate, вам нужно установить следующую функцию в качестве обратного вызова функции setstate, например:

this.setState({value:1}, callBack)

Я надеюсь, что эта помощьЕсли вы хотите, мы можем поговорить с вами или я могу объяснить вам лучше.

...