Является ли реакция setState синхронной или асинхронной?

React.js

Прежде чем представить эту проблему, давайте рассмотрим пример:

state = {
    number:1
};
componentDidMount(){
    this.setState({number:3})
    console.log(this.state.number)
}

Прочитав этот пример, многие мелкие партнеры могут подсознательно подумать, что setState — это асинхронный метод, но на самом деле setState не имеет асинхронного оператора Причина, по которой существует асинхронный метод, — механизм производительности самого фреймворка реакции. Поскольку каждый вызов setState запускает обновление, асинхронная операция предназначена для повышения производительности, объединения нескольких состояний для обновления вместе и сокращения количества вызовов повторной визуализации.

Представьте, что в компоненте выполняется следующий фрагмент кода:

for ( let i = 0; i < 100; i++ ) {
    this.setState( { num: this.state.num + 1 } );
}

Если бы setState был синхронно исполняемым механизмом, компонент перерисовывался бы 100 раз, что значительно снижает производительность.

Очевидно, React тоже подумал об этой проблеме, поэтому сделал несколько специальных оптимизаций для setState:

React объединит несколько вызовов setState в один для выполнения, то есть при выполнении setState данные в состоянии будут обновлены не сразу

Это тоже хорошее подтверждение только что приведенного примера.

Но часто в реальных разработках нам может понадобиться получать обновленные данные синхронно, так как же их получить? Вот некоторые часто используемые методы:

Перезвоните

setState предоставляет разработчикам функцию обратного вызова, которая позволяет получать обновленные данные в режиме реального времени. Или возьмем пример только что в качестве демонстрации:

state = {
    number:1
};
componentDidMount(){
    this.setState({number:3},()=>{
        console.log(this.state.number)
    })
}

В это время вы можете видеть, что данные, напечатанные на консоли, являются самыми последними, и мы также получаем последние данные в режиме реального времени.

setTimeout

Как мы упоминали выше, setState сам по себе не является асинхронным методом, причина, по которой он демонстрирует асинхронную форму, заключается в механизме оптимизации производительности самой среды реагирования. Итак, исходя из этого, если мы можем обойти механизм реагирования, можем ли мы сделать setState манифестом в синхронной форме?

Лучше сказать, что больше слов не так хорошо, как практика кода. Практика - единственный критерий проверки истины. Давайте изменим код на основе предыдущего примера:

state = {
    number:1
};
componentDidMount(){
    setTimeout(()=>{
      this.setState({number:3})
      console.log(this.state.number)
    },0)
}

Вы можете видеть, что данные, напечатанные на консоли, являются последними данными на данный момент. Это также прекрасно подтверждает правильность нашего предположения.

Изменить состояние в собственном событии

Выше было подтверждено механизм избегания реакции, а обновленные данные могут быть получены синхронно, поэтому помимо setTimeout возможно и в нативных событиях. Или посмотрите на пример:

state = {
    number:1
};
componentDidMount() {
    document.body.addEventListener('click', this.changeVal, false);
}
changeVal = () => {
    this.setState({
      number: 3
    })
    console.log(this.state.number)
}

После практики тот же метод также осуществим.

Суммировать:

Сам setState не является асинхронным, просто потому, что механизм оптимизации производительности реакции отражен как асинхронный. Он асинхронен в функции жизненного цикла или области действия и синхронен в родной среде.

Наконец, если вы хотите обсудить и изучить интерфейс со мной, вы можете обратить внимание на мой официальный аккаунт, время от времени обновлять галантерею и присоединиться к технической группе для общения и обсуждения.

В этой статье используетсяmdniceнабор текста