ReactJS - вызывается, но DOM не обновляется

Это случилось со мной несколько раз. Мне всегда удалось обойти эту проблему, но я все еще заинтригован, чтобы понять, почему это происходит, и что я пропустил.

По существу, если у меня есть условие в моем методе render, который указывает класс для моего div:

let divClass = this.state.renderCondition ? 'red' : 'blue';

По умолчанию я устанавливаю renderCondition в моем состоянии на false.

Если я затем определяю обработчик onClick на кнопке (следующим образом) и нажимаю кнопку, пока вызывается IS, DOM обновляется NOT. То есть класс не меняется.

onClickCompile: function() {

   this.setState({renderCondition: true}, function() {

        synchronousSlowFunction();
   });
}

Кажется, что это связано с медленным синхронным кодом, поскольку код быстро и просто обновляется соответствующим образом DOM IS.

Если я завершу вызов synchronousSlowFunction в тайм-аут 500 миллисекунд, все будет работать так, как ожидалось. Однако я хотел бы понять, что я неправильно понял, так что мне не нужен этот хак.

Ответ 1

Можете поделиться кнопкой на код клика? Возможно, я ошибаюсь, но это похоже на неправильно установленную кнопку прослушивания onClick.

Убедитесь, что обратный вызов onClick определен без(), т.е.

<button onClick={this.something} />

вместо:

<button onClick={this.something()} />

Опубликуйте больше кода, чтобы мы могли получить более качественную (большую) картинку

Ответ 2

SyncousSlowFunction, как вы упомянули, синхронный. Это означает, что он блокирует ваш компонент во время работы. Это означает, что реакция не может обновить ваш компонент, потому что он должен ждать завершения функции обратного вызова, пока не сможет вызвать render с обновленными значениями. Обертка setTimeout делает вызов асинхронным, так что реагирующий может визуализировать/обновить ваш компонент, пока функция выполняет свою работу. Работает не задержка, а просто обратный вызов, который не блокирует рендеринг. Вы также можете включить в Promise или сделать асинхронную медленную функцию, чтобы предотвратить блокировку рендера.

Ответ 3

Попробуйте что-то вроде этого:

this.setState((state) => ({
   ...state, renderCondition: true
}));

Может быть, вы делаете другой setState для renderCondition, где приведенный выше код должен исправить такие вещи.

или, возможно, попробуйте использовать PureComponent

import React, { PureComponent } from 'react'

export default class TablePreferencesModal extends PureComponent {
  render() {
    return (
      <div>

      </div>
    )
  }
}

Ответ 4

После установки состояния используйте эту строку

this.setState({})