#reactjs #state
#reactjs #состояние
Вопрос:
Я создаю приложение-калькулятор в React. Здесь у меня есть компонент приложения и компонент кнопки. Когда я нажимаю кнопку, несмотря на то, что я устанавливаю значение параметра (event.target.getAttribute(‘data-number’), консоль регистрирует число, отличное от атрибута кнопки.
Когда я нажимаю кнопку с «data-number = 1», состояние «результат» устанавливается на «0». Затем я нажимаю кнопку с «data-number = 7», состояние «результат» устанавливается на «1». Интересно, что происходит и как исправить эту проблему.
class App extends React.Component {
state = { result: 0 };
currentNumber = (number) => {
this.setState({ result: number })
console.log("Number from Button", number); // 1
console.log("Current number in state", this.state.result); // 0
}
render() {
return (
<div>
<Button onClick = {this.currentNumber} />
</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>
</ul>
Комментарии:
1. Извините, я просто вырезал остальную часть своего кода в компоненте Button. Это должно быть <li><кнопка data-number=»1″ onClick={событие => this.props.onClick(event.target.getAttribute(‘data-number’))}>1</button></li>, <li>=»2″ onClick={событие => this.props.onClick(event.target.getAttribute(‘data-number’))}>2</button></li>, … <li><кнопка data-number=»7″ onClick={событие =>this.props.onClick(event.target.getAttribute(‘data-number’))}>7</button></li>
2. можете ли вы добавить этот код в текст вашего вопроса для ясности?
Ответ №1:
Вызов setState
является асинхронным, что означает, что состояние не обновляется сразу. Вы можете передать обратный вызов, который запускается после обновления состояния:
this.setState({ result: number }, () => {
console.log("Number from Button", number); // 1
console.log("Current number in state", this.state.result); // 1
})
Комментарии:
1. Спасибо! Я не уверен, правильно ли я понимаю, но я прочитаю документ подробнее..
Ответ №2:
Как упоминал @Smarticles101, setState
является асинхронным. Вот ваш код, работающий правильно.
Обратите внимание на разницу между журналами обратного вызова и внешними журналами обратного вызова. Проверьте эти документы в setState для получения дополнительной информации.
class App extends React.Component {
state = { result: 0 };
currentNumber = (number) => {
this.setState({ result: number }, () => {
console.log("Callback, number: ", number);
console.log("Callback, result: ", this.state.result);
})
console.log("Outside callback, number: ", number);
console.log("Outside callback, result: ", this.state.result);
}
render() {
return (
<div>
<Button onClick={this.currentNumber} />
</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="7" onClick={event => this.props.onClick(event.target.getAttribute('data-number'))}>7</button></li>
</ul>
)
}
}
ReactDOM.render((<App/>), document.getElementById('testing'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="testing" />
Комментарии:
1. Спасибо! Я все еще не понимаю асинхронную часть, но я буду искать дальше..