В чем разница между componentWillMount и componentDidMount в ReactJS?

91

Я просмотрел документацию Facebook по адресу ( React.Component ), и там упоминается, как componentWillMountвызывается на клиенте / сервере, тогда componentDidMountкак вызывается только на клиенте. Что componentWillMountделать с сервером?

BlueElixir
источник

Ответы:

70

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

Это редко нужно, и совсем не с классами ES6.

Разбойник
источник
Это не то же самое, что конструктор. В строгом режиме в dev, например, ваш конструктор будет вызываться дважды (для двух разных экземпляров), но только один будет иметь вызов componentWillMount - stackoverflow.com/questions/61254372/…
adarsh
63

constructorметод не является таким же , как componentWillMount.

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

Тем не менее, отправка оттуда componentWillMountпросто прекрасна.

из выпуска github :

Это происходит, когда dispatch () внутри конструктора одного компонента вызывает setState () внутри другого компонента. React отслеживает «текущего владельца» для таких предупреждений - и думает, что мы вызываем setState () внутри конструктора, когда технически конструктор вызывает setState () внутри какой-либо другой части приложения. Я не думаю, что мы должны справляться с этим - просто React изо всех сил старается делать свою работу. Решение, как вы правильно заметили, - вместо этого использовать dispatch () внутри componentWillMount ().

Лиран Браймер
источник
Это определенно не хорошо при любых обстоятельствах, в зависимости от того, что происходит componentXxxMount, например, использование Ajax willMountможет вызвать проблемы.
Дэйв Ньютон,
2
@DaveNewton Я не сказал, что все в порядке. Я просто привел пример, в котором есть разница, чтобы доказать, что ответ «componentWillMount, по сути, конструктор» неверен. Спасибо за разъяснение
Лиран Браймер
@LiranBrimer Этот ответ становится неточным, поскольку componentWillMount устарел и перестанет работать в версиях 0.16 и 0.17 соответственно, особенно в отношении «Однако отправка из componentWillMount в порядке». заявление
Брайан Вебстер
37

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

Андерс Экдал
источник
10
componentWillMountбудет вызван на сервере и на клиенте. см .: facebook.github.io/react/docs/…
Дэвид,
1
@DaveNewton как? В нем не говорилось, componentWillMountчто клиенту не
позвонят
7
@AyushShanker ИМО, важно предоставить не вводящую в заблуждение информацию. Не будучи явным, есть место для неправильного толкования: документы явные. Вы правы, что это тоже явно не противоречит.
Дэйв Ньютон,
31

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

componentDidMountвыполняется ПОСЛЕ первоначального renderобновления DOM (но, что особенно важно, ДО того, как это обновление DOM передается браузеру, что позволяет вам выполнять все виды расширенного взаимодействия с самой DOM). Это, конечно, может происходить только в самом браузере и поэтому не происходит как часть SSR, поскольку сервер может генерировать только разметку, а не сам DOM, это делается после того, как он будет отправлен в браузер при использовании SSR.

Вы говорите, что расширенное взаимодействие с DOM? Что зааааааааааааааааааааааааааа болееина) более точным, поскольку DOM обновлен (но пользователь еще не видел обновления в браузере), можно перехватить фактическое рисование на экране, используя, window.requestAnimationFrameа затем выполнить такие действия, как измерение фактического Элементы DOM, которые будут выводиться, для которых вы можете выполнять дальнейшие изменения состояния, что очень полезно, например, для анимации по высоте элемента с неизвестным содержимым переменной длины (поскольку теперь вы можете измерить содержимое и назначить высоту анимации), или чтобы избежать сценариев вспыхивания содержимого во время некоторого изменения состояния.

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

алехилл
источник
1
Я не думаю , что добавление setStateв componentDidMountвызовет бесконечный цикл.
Мэдди
« поскольку в противном случае может возникнуть бесконечный цикл, потому что изменение состояния также вызовет повторный рендеринг и, следовательно, другой componentDidMount. и так далее, и так далее », это совсем не так. Изменения состояния вызовут повторный рендеринг, но он не будет запускаться componentDidMountснова и снова. componentDidMount вызывается только один раз при монтировании компонента.
hussain.codes
9

Согласно документации ( https://facebook.github.io/react/docs/react-component.html )

Методы с префиксом will вызываются прямо перед тем, как что-то произойдет, и

Методы с префиксом did вызываются сразу после того, как что-то происходит.

Велу
источник
2

componentWillMount https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/

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

Невозможно «приостановить» рендеринг, чтобы дождаться прибытия данных. Вы не можете вернуть обещание из componentWillMount или каким-то образом обжаловать в setTimeout.

https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/birth/premounting_with_componentwillmount.html

наш Компонент не будет иметь доступа к собственному пользовательскому интерфейсу (DOM и т. д.). У нас также не будет доступа к дочерним ссылкам, потому что они еще не созданы. ComponentWillMount () дает нам возможность обработать конфигурацию, обновить наше состояние и в целом подготовиться к первому рендерингу. Это означает, что мы можем начать выполнять вычисления или процессы на основе значений prop.

zloctb
источник
1

Пример использования componentWillMount ()

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

componentWillMount() {
  this.setState({ todayDate: new Date(Date.now())});
}

Пример использования componentDidMount ()

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

componentDidMount() {
  this.interval = setInterval(this.fetchNews, 3600000);
}
Лалит Тяги
источник
0

ComponentDidMount()Метод изменяет только текущую страницу в компонентах класса, но ComponentWillMount()изменяет все страницы, на которые влияетsetStates()

Еще один
источник