Подтвердить что ты не робот

React shouldComponentUpdate() вызывается, даже если реквизит или состояние для этого компонента не изменились

Я добавил метод жизненного цикла в свой компонент React

  shouldComponentUpdate(nextProps, nextState) {
    console.log(nextProps, nextState);
    console.log(this.props, this.state);

    return false;  
  },

Моя проблема заключается в том, что этот метод вызывается на компоненте, даже когда nextProps и nextState точно такие же, как текущие реквизиты и состояние. Когда я сравниваю инструкции console.log для nextProps и this.props, они точно такие же. То же самое с состоянием.

Так почему же должен быть вызванComponentUpdate?

Он вызывается всякий раз, когда я изменяю состояние родительского компонента. Но ни один из реквизитов или состояний не меняется на фактическом компоненте. Так почему он называется?

fyi, я использую React with Meteor

Дальнейшее уточнение:

Мне интересно, почему функция shouldComponentUpdate вызывается в первую очередь. Ни одно государство или реквизит этого компонента не меняется. Но состояние родительского компонента меняется.

4b9b3361

Ответ 1

Реакция автоматически вызывает shouldComponentUpdate, она запускается до начала процесса повторного рендеринга (в данном случае вашего родительского компонента). Поэтому, естественно, это часто называют.

Реализация этой функции по умолчанию возвращает true, поэтому для остановки повторной обработки вам нужно вернуть false здесь:

  shouldComponentUpdate(nextProps, nextState) {
    console.log(nextProps, nextState);
    console.log(this.props, this.state);

    return false;  
  }

Дополнительные проблемы, страница ответов

Итак, вкратце, React избегает выполнения дорогостоящих операций DOM, необходимых для согласования поддеревьев DOM, позволяя пользователю коротко замыкать процесс с использованием shouldComponentUpdate,

Ответ 2

Цель shouldComponentUpdate - указать, следует ли вызывать render. В вашем случае какой-то родительский компонент отобразил и указал, что он хочет также отобразить экземпляр вашего дочернего компонента.

shouldComponentUpdate - это ваша возможность закоротить этот рендер и сказать: "Не беспокойтесь, здесь ничего не изменилось".

Теперь, на ваш вопрос, "почему он даже звонил, потому что ничего не изменилось"? Реакция не сравнивает старый и новый реквизит. Вы можете получить mixin, чтобы сделать это за вас (т.е. PureRenderMixin), но по умолчанию React просто позволяет выполнить рендеринг.

Причина React не делает само сравнение по нескольким причинам. Во-первых, экономия производительности пропущенного рендера может быть незначительной по сравнению с анализом реквизита и состояния. Поскольку механизм рендеринга React уже оптимизирован, чтобы избежать ненужных манипуляций с DOM, он может просто предположить, что компонент нуждается в обновлении и ожидании разумной производительности. Во-вторых, сделать сравнение не совсем прямолинейно. Является ли ваш пропринтер примитивным?, Неизменяемым?, массив?, сложный объект?, Будет ли нужно глубокое сравнение?

React model: "Мы будем обрабатывать все по умолчанию. Если вы хотите что-то отказаться от производительности, тогда расскажите нам, выполнив shouldComponentUpdate".

Ответ 3

shouldComponentUpdate() вызывается каждый раз:

  • реквизит обновляется каждой повторной обработкой родительского компонента. Это включает в себя все сценарии, в которых повторная обработка происходит с точно такими же значениями поддержки.
  • состояние обновляется по вызову setState() (единственный способ разрешен реагировать). Это включает все сценарии, в которых значение состояния точно такое же.

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

Кроме того, 'shouldComponentUpdate() `, в качестве отдельного метода проверки изменений и обновления только если что-то изменилось, делает приятный поддерживаемый код:

  • создайте первую версию без shouldComponentUpdate() и убедитесь, что один и тот же набор реквизитов и состояний приведет к тому, что результат будет выполнен.
  • добавить и отладить shouldComponentUpdate()

Относительно легко отлаживать "конечный автомат", который принимает входные данные (состояние и реквизит) и выводит результат. Намного сложнее отладить машину, которая управляет изменениями состояния.