TransWikia.com

Почему отстает state? React

Stack Overflow на русском Asked by bazmexes on January 19, 2021

Почему при нажатии на 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 Answers

Поскольку setState работает асинхронно, то для того что бы получить актуальное состояние стейта можно:

<div key={index} onClick={handleClick}> 
  {option} 
</div>
  1. Использовать prevState (назвать можно как угодно):

    handleClick (event) {
      this.setState(prevState => {
        console.log(prevSate)
        return {currentTimeFilter: event.target.innerHTML}
      )
    })
    
  2. Добавить callback вторым параметром в setSate:

    handleClick (event) {
      this.setState({currentTimeFilter: event.target.innerHTML}, _changeCurrent)
    }
    
    _changeCurrent () {
      console.log("current", this.state.currentTimeFilter)
    }
    

Отдельно стоит отметить что изменение имен классов напрямую не является рекомендованным способом взаимодействия с ними, что бы Ваше приложение работало оптимально лучше придерживаться именно react-way'a.

Correct answer by Vasily on January 19, 2021

setState работает асинхронно. У вас сначала выполняется весь onClick, а потом уже setState

документация

В настоящее время setState работает асинхронно внутри обработчиков событий.

Это даёт гарантию, например, когда Родитель и Ребёнок вызывают setState во время клика, Ребёнок не будет рендериться дважды. Вместо этого React «откладывает» обновление состояния в самый конец событий в браузере. Это помогает сильно повысить производительность больших приложений.

Кроме этого, ваш подход неправильный, т.к. вы изменяете DOM элемент в обход React и, если React'у потребуется перерисовать измененный элемент .PlaylistSelect, то он его перерисует без учета изменений, и он вновь будет иметь класс PlaylistSelect--active

Answered by xydope on January 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP