archi_kud
@archi_kud
Frontend Developer

Как получить текущее state?

Здравствуйте, как получить текущее состояние компонента, а не старое. Пиши калькулятор и на выводе значение вместо текущего результата выводится предыдущий результат.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import Actions from './components/actions';
import Value from './components/value';

import './style.css';

class App extends Component {

	state = {
		input: '',
		output: '0'
	};

	checkValue = value => {
		let state = this.state.input;
		let lastState = state[state.length - 1];

		if (value === '+' || value === '-' || value === 'x' || value === '÷') {
			if (lastState === '+' || lastState === '-' || lastState === 'x' || lastState === '÷' || state.length === 0) {
				return false;
			} else {
				return true;
			}
		}

		return true;
	};

	showAnswer = () => {
		let input = this.state.input.split('');

		input.forEach(i => {
			let index = input.indexOf(i);

			if (i === '÷') {
				input.splice(index, 1, '/');
			} else if (i === 'x') {
				input.splice(index, 1, '*');
			}
		});

		input = input.join('');

		try {
			let result = eval(input);

			this.setState({
				output: result
			});

		} catch (error) {
			console.log('Закончите выражение');
		}
	};

	addValue = event => {
		event.persist();

		let currentValue = event.target.textContent;

		if (this.checkValue(currentValue)) {
			if (currentValue === '=') {
				this.setState({
					input: this.state.output.toString()
				});

				this.showAnswer();
			} else if (currentValue === 'C') {
				this.setState({
					input: this.state.input.slice(0, -1)
				});
			} else {
				this.setState(({ input }) => {
					return {
						input: input + currentValue
					};
				});
			}
		}
	};

	render() {
		const actions = [
			{ label: '%', className: 'action white-button' },
			{ label: '+', className: 'action white-button' },
			{ label: 'C', className: 'action white-button' },
			{ label: '÷', className: 'action purple-button' },

			{ label: '7', className: 'action white-button' },
			{ label: '8', className: 'action white-button' },
			{ label: '9', className: 'action white-button' },
			{ label: 'x', className: 'action purple-button' },

			{ label: '4', className: 'action white-button' },
			{ label: '5', className: 'action white-button' },
			{ label: '6', className: 'action white-button' },
			{ label: '-', className: 'action purple-button' },

			{ label: '1', className: 'action white-button' },
			{ label: '2', className: 'action white-button' },
			{ label: '3', className: 'action white-button' },
			{ label: '+', className: 'action purple-button' },

			{ label: '0', className: 'action white-button' },
			{ label: '.', className: 'action white-button' },
			{ label: '=', className: 'action', id: 'equally' }
		];

		return (
			<div id='calculator'>
				<Value input = { this.state.input } output = { this.state.output }/>
				<Actions actions = { actions } addValue = { this.addValue }/>
			</div>
		);
	}
}

ReactDOM.render(<App />, document.getElementById('main-wrap'));
  • Вопрос задан
  • 201 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
this.setState({
  input: this.state.output.toString()
});

this.showAnswer();

В showAnswer вы, надо полагать, ждёте, что свойство input будет равно output.toString(). Это вряд ли. Читаем документацию внимательнее:

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.

Ну и про использование колбека там дальше. Так что правильно будет как-то так:

this.setState({
  input: this.state.output.toString()
}, this.showAnswer);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы