Почему componentWillMount не должен использоваться?

запуск вызова сервера для извлечения данных в методе жизненного цикла componentWillMount плохая практика?

и почему лучше использовать componentDidMount.

5 ответов


цитировать @Dan Abramov

на будущие версии React мы ожидаем, что componentWillMount будет срабатывать более одного раза в некоторых случаях, поэтому вы должны использовать componentDidMount для сетевых запросов.

подробнее здесь.


обновление - май / 2018
Существует новая функция для react в рабочем прогрессе под названием асинхронность перевода.
Как реагировать v16.3.2 эти методы не являются "безопасными" для использования:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

вы можете прочитать больше об этом в docs.


как правило не используйте componentWillMount вообще (если вы используете es6 class синтаксис). используйте метод.
Этот метод жизненного цикла хорош для инициализации состояния синхронизации.
componentDidMount С другой стороны, это хорошо для асинхронного управления состоянием.

почему?
Ну, когда вы делаете асинхронный запрос в constructor / componentWillMount вы делаете это перед render вызывается к моменту завершения асинхронной операции render способ скорее всего уже закончено и нет смысла устанавливать "начальное состояние" на этом этапе, не так ли?.
Я не уверен, что это ваш случай здесь, но большинство случаев, когда разработчики хотят инициировать состояние асинхронно в componentWillMount чтобы избежать второй render звонок. но вы не можете избежать этого, не так ли, как упоминалось выше,render будет срабатывать в любом случае до завершения асинхронной операции.
Поэтому, лучшее время для вызова асинхронной операции после render назвал и компонент установлен (вы можете установить null или пустой <div/>), а затем получить ваши данные, установить состояние и сделать его заново рендерить соответственно.


componentDidMount является лучшим местом для размещения вызовов для получения данных по двум причинам:

  1. используя componentDidMount дает понять, что данные не будут загружены до завершения начального рендеринга. Вам нужно правильно настроить начальное состояние, поэтому вы не получите undefined состояние, которое вызывает ошибки.

  2. Если вам нужно отобразить приложение на сервере,componentWillMount будет вызываться дважды(на сервере и опять же на клиенте), что, вероятно, не то, что вы хотите. Поставив код загрузки данных в componentDidMount гарантирует, что данные извлекаются только из клиента. Как правило, вы не должны добавлять побочные эффекты в componentWillMount.


насколько я понимаю, одна из самых больших причин связана с настройка правильных ожиданий для разработчиков читать код.

Если мы используем componentWillMount заманчиво думать, что выборка успеет произойти, тогда компонент "сделал" монтирование, и затем произойдет первый рендеринг. Но это не так. Если мы сделаем асинхронный вызов (например, вызов API с обещаниями), компонент фактически запустится render перед возвратом выборки и установите состояние компонента (или измените состояние Redux или что-либо еще).

Если мы вместо этого используем componentDidMount, тогда ясно, что компонент будет отображаться по крайней мере один раз, прежде чем вы вернете какие-либо данные (потому что компонент уже сделал mount). Таким образом, по расширению также ясно, что мы должны обрабатывать начальное состояние таким образом, чтобы компонент не ломался при первом ("пустом") рендеринге.


компонентный жизненный цикл установки

  • конструктор()
  • componentWillMount () /UNSAFE_componentWillMount () (react 16)
  • render ()
  • componentDidMount()

конструктор и componentWillMount оба вызова перед вызовом render (), который отвечает за рендеринг страницы.

здесь инициализированное состояние выполняется в конструкторе, а api вызывается в componentDidMount из-за асинхронных вызовов.

ComponentWillMount был хорош для инициализированного состояния до ES6 когда конструктора не было. Но теперь ComponentWillMount ни на что не годится, и команда react думает об этом после react 17.