Почему документы React рекомендуют использовать AJAX в componentDidMount, а не componentWillMount?


102

Я понимаю, почему componentDidMountэто подходит для всего, что требует доступа к DOM, но запрос AJAX не обязательно или обычно требует этого.

Что дает?


@FurkanO Я думаю, он имел в виду доступ к элементам DOM, отображаемым компонентом. И он полностью прав, потому что, если бы вы попытались получить доступ к указанным элементам в componentWillMountнем, он потерпел бы неудачу, учитывая, что компонент ... не смонтировался.
ZekeDroid 07

@AlanH. Удалил мой вопрос, конечно, у вас есть доступ к dom на componentDidMount. Это правило, объяснять нечего. Спасибо.
FurkanO

На мой взгляд, почему мы вызываем функцию Ajax после componentDidMount, мы должны сначала убедиться, что элемент отрисовывается плавно в начале. После этого мы можем выполнить вызов ajax. Если мы сначала вызовем ajax и произойдет какая-то ошибка, это вызовет проблемы при рендеринге
Фарис Райхан,

Ответы:


62

componentDidMountдля побочных эффектов. Добавление слушателей событий, AJAX, изменение DOM и т. Д.

componentWillMountредко бывает полезным; особенно если вы заботитесь о рендеринге на стороне сервера (добавление прослушивателей событий вызывает ошибки и утечки, а также множество других вещей, которые могут пойти не так).

Говорят об удалении componentWillMountиз компонентов класса, поскольку он служит той же цели, что и конструктор. Он останется на createClassкомпонентах.


1
Добавление прослушивателей событий вызывает ошибки и утечки постоянно на сервере или только в componentWillMount? Я действительно не вижу разницы.
Алан Х.

18
@Alan - Если вы используете React как на стороне клиента, так и на стороне сервера, вы обнаружите, что все, что находится внутри, componentWillMountбудет выполняться на стороне сервера . Если бы вы использовали, componentDidMountто это будет выполняться только на стороне клиента. В результате размещение вещей, componentWillMountкоторые выполняют внешние взаимодействия или привязаны к событиям и т. Д., Не является хорошей идеей. Если вы не планируете рендерить компоненты на стороне сервера, это все равно не лучшая идея только для потенциальной переносимости кода. Это все выходит за рамки основной причины, по которой это плохо, что объясняется в ответе @daniula.
Майк Драйвер

3
componentWillMount запускается на сервере, а componentWillUnmount (где вы удаляете слушателей) - нет. Это заставит вас добавить слушателей и никогда не очищать их.
Brigand

Люди из основной команды React рассматривают возможность удаления componentWillMount из будущих версий.
cchamberlain

1
@AnkitSinghaniya это нарушит рендеринг сервера и неглубокие модульные тесты.
Brigand

36

У меня тоже была такая же проблема в начале. Я решил попробовать сделать запросы, componentWillMountно это закончилось различными небольшими проблемами.

Я запускал рендеринг, когда вызов ajax завершался с новыми данными. В какой-то момент рендеринг компонента занимал больше времени, чем получение ответа от сервера, и в этот момент обратный вызов ajax запускал рендеринг на отключенном компоненте. Это своего рода крайний случай, но его, вероятно, больше, поэтому безопаснее придерживаться componentDidMount.


Хорошо спасибо. Думал, что это может быть что-то в этом роде, но вы правы, удивительно, что запрос ajax может завершиться до того, как завершится рендеринг.
Алан Х.

1
@daniula Вы уверены? Как можно завершить запрос AJAX до рендеринга?
Леон Грапентин

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

1
Конструктор класса @SooChengKoh ES6 эквивалентен componentWillMount, поэтому вы все равно должны продолжать использовать componentDidMountдля своих вызовов ajax.
daniula 06

1
@SooChengKoh - определенно не должен делать ничего в конструкторе, что приведет к состоянию, которое должно быть установлено, что приведет к условиям гонки на клиенте и сервере. Вы никогда не должны вызывать setStateконструктор компонентов, и у вас нет возможности определить, когда будет завершен вызов AJAX. twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

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

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


1
componentWillMountне запускает повторную визуализацию только потому, что новое состояние определено перед первой визуализацией. Но если setStateвызывается в обратном вызове AJAX, он определенно будет вызван после первого рендеринга и вызовет повторный рендеринг.
webdif 07
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.