Почему отстает state? React
Почему при нажатии на div в консоле показывается старый state, хотя должен быть новый?
А при следующем нажатии показывается тот state, который должен был быть на первом нажатии:
<div key={index}
onClick={(e)=> {
this.setState({currentTimeFilter: e.target.innerHTML})
this._changeCurrent(e)}
}
className="PlaylistSelect__item"
>
{option}
</div>
_changeCurrent(e){
console.log('current', this.state.currentTimeFilter)
e.target.closest('.PlaylistSelect').classList.remove('PlaylistSelect--active')
}
Ответы (2 шт):
setState работает асинхронно. У вас сначала выполняется весь onClick, а потом уже setState
В настоящее время setState работает асинхронно внутри обработчиков событий.
Это даёт гарантию, например, когда Родитель и Ребёнок вызывают setState во время клика, Ребёнок не будет рендериться дважды. Вместо этого React «откладывает» обновление состояния в самый конец событий в браузере. Это помогает сильно повысить производительность больших приложений.
Кроме этого, ваш подход неправильный, т.к. вы изменяете DOM элемент в обход React и, если React'у потребуется перерисовать измененный элемент .PlaylistSelect, то он его перерисует без учета изменений, и он вновь будет иметь класс PlaylistSelect--active
Поскольку setState работает асинхронно, то для того что бы получить актуальное состояние стейта можно:
<div key={index} onClick={handleClick}>
{option}
</div>
Использовать
prevState(назвать можно как угодно):handleClick (event) { this.setState(prevState => { console.log(prevSate) return {currentTimeFilter: event.target.innerHTML} ) })Добавить
callbackвторым параметром вsetSate:handleClick (event) { this.setState({currentTimeFilter: event.target.innerHTML}, _changeCurrent) } _changeCurrent () { console.log("current", this.state.currentTimeFilter) }
Отдельно стоит отметить что изменение имен классов напрямую не является рекомендованным способом взаимодействия с ними, что бы Ваше приложение работало оптимально лучше придерживаться именно react-way'a.