Ответ 1
Причина setState асинхронна, вы не можете ожидать обновленное значение state
сразу после setState
, если вы хотите проверить значение, используйте метод callback
. Передайте метод в качестве обратного вызова, который будет выполнен после завершения setState
его задачи.
Почему setState асинхронен?
Это связано с тем, что setState
изменяет state
и вызывает повторный рендеринг. Это может быть дорогостоящей операцией и сделать ее synchronous
может оставить браузер безответным.
Таким образом, вызовы setState
asynchronous
, а также пакет для лучшего опыта и производительности интерфейса.
Из Doc:
setState() не сразу мутирует this.state, но создает ожидающий переход состояния. Доступ к this.state после вызова этого метод может потенциально вернуть существующее значение. Здесь нет гарантия синхронной работы вызовов setState и вызовов может быть собраны для повышения производительности.
Использование метода обратного вызова с помощью setState:
Чтобы проверить обновленное значение state
сразу после setState
, используйте метод обратного вызова, например:
setState({ key: value }, () => {
console.log('updated state value', this.state.key)
})
Проверьте это:
class NightlifeTypes extends React.Component {
constructor(props) {
super(props);
this.state = {
barClubLounge: false,
seeTheTown: true,
eventsEntertainment: true,
familyFriendlyOnly: false
}
this.handleOnChange = this.handleOnChange.bind(this);
}
handleOnChange = (event) => {
let value = event.target.checked;
if(event.target.className == "barClubLounge") {
this.setState({ barClubLounge: value}, () => { //here
console.log(value);
console.log(this.state.barClubLounge);
//both will print same value
});
}
}
render() {
return (
<input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
)
}
}
ReactDOM.render(<NightlifeTypes/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>