Dlaczego dokumentacja Reacta zaleca robienie AJAX w componentDidMount, a nie w componentWillMount?
102
Rozumiem, dlaczego componentDidMountjest to odpowiednie dla wszystkiego, co wymaga dostępu do DOM, ale żądanie AJAX niekoniecznie lub zwykle tego wymaga.
@FurkanO Myślę, że miał na myśli dostęp do elementów DOM renderowanych przez komponent. I ma całkowitą rację, ponieważ próba uzyskania dostępu do wspomnianych elementów componentWillMountzakończy się niepowodzeniem, biorąc pod uwagę, że komponent ... nie został zamontowany.
ZekeDroid
@AlanH. Usunąłem moje pytanie, oczywiście masz dostęp do domeny na componentDidMount. To jest zasada, nie ma nic do wyjaśnienia. Dzięki.
FurkanO
Moim zdaniem powodem wywołania funkcji Ajax po komponencie componentDidMount jest to, że musimy najpierw upewnić się, że element renderuje się płynnie na początku. Następnie możemy wykonać połączenie AJAX. Jeśli najpierw zadzwonimy do Ajaxa i stanie się coś błędu, spowoduje to problem z renderowaniem
Faris Rayhan
Odpowiedzi:
62
componentDidMountdotyczy skutków ubocznych. Dodawanie detektorów zdarzeń, AJAX, mutowanie DOM, itp.
componentWillMountrzadko się przydaje; szczególnie jeśli zależy Ci na renderowaniu po stronie serwera (dodanie detektorów zdarzeń powoduje błędy i wycieki oraz wiele innych rzeczy, które mogą pójść źle).
Mówi się o usuwaniu componentWillMountz komponentów klasy, ponieważ służy to temu samemu celowi, co konstruktor. Pozostanie na createClasskomponentach.
Dodanie detektorów zdarzeń powoduje błędy i przecieki przez cały czas na serwerze, czy po prostu componentWillMount? Naprawdę nie widzę różnicy.
Alan H.
18
@Alan - Jeśli używasz React zarówno po stronie klienta, jak i serwera, zauważysz, że wszystko w środku componentWillMountzostanie wykonane na renderowaniu po stronie serwera. Gdybyś używał, componentDidMountto byłby wykonywany tylko po stronie klienta. W rezultacie umieszczanie rzeczy, componentWillMountktóre wykonują zewnętrzne interakcje lub są powiązane ze zdarzeniami itp., Nie jest dobrym pomysłem. Jeśli nie planujesz renderować swoich komponentów na serwerze, nadal nie jest to dobry pomysł tylko ze względu na potencjalną przenośność kodu. To wszystko jest poza głównym powodem, dla którego jest zły, co zostało wyjaśnione w odpowiedzi @daniula.
Mike Driver
3
componentWillMount jest uruchamiany na serwerze, ale componentWillUnmount (gdzie usuwasz detektory) nie. Spowodowałoby to dodanie słuchaczy i nigdy ich nie porządkowanie.
Brigand
Osoby z podstawowego zespołu React rozważają usunięcie komponentu WillMount z przyszłych wersji.
cchamberlain
1
@AnkitSinghaniya przerwałoby renderowanie serwera i płytkie testy jednostkowe.
Brigand
36
Na początku też miałem ten sam problem. Postanowiłem spróbować wysyłać prośby, componentWillMountale kończy się to różnymi drobnymi problemami.
Wyzwalałem renderowanie, gdy połączenie Ajax zakończyło się z nowymi danymi. W pewnym momencie renderowanie komponentu zajęło więcej czasu niż uzyskanie odpowiedzi z serwera i w tym momencie wywołanie zwrotne ajax wyzwalało renderowanie na niezmontowanym komponencie. Jest to rodzaj skrajnego przypadku, ale prawdopodobnie jest ich więcej, więc bezpieczniej jest się trzymać componentDidMount.
Ok, dzięki. Myślałem, że może to być coś takiego, ale masz rację, zaskakujące jest, że żądanie AJAX mogło zakończyć się przed renderowaniem.
Alan H.
1
@daniula Czy na pewno? W jaki sposób żądanie AJAX może zakończyć się przed renderowaniem?
Leon Grapenthin
4
To jest świat asynchroniczny przeglądarki. Nigdy nie należy zakładać, że jedna funkcja zawsze będzie szybsza od reszty. Jak wspomniałem, jest to przypadek skrajny i prawdopodobnie oznacza, że powinieneś zoptymalizować proces renderowania, ale użycie odpowiedniej metody cyklu życia znacznie ułatwi ci życie w tym momencie.
daniula
1
Konstruktor klasy @SooChengKoh ES6 jest odpowiednikiem componentWillMount, więc nadal powinieneś używać go componentDidMountdo wywołań Ajax.
daniula
1
@SooChengKoh - Zdecydowanie nie należy robić nic w konstruktorze, co doprowadzi do stanu, który należy ustawić, co doprowadzi do warunków wyścigu na kliencie i serwerze. Nigdy nie powinieneś wywoływać setStatekonstruktora komponentu i nie masz możliwości określenia, kiedy wywołanie AJAX się zakończy. twitter.com/dan_abramov/status/576453138598723585
cchamberlain
3
Zgodnie z dokumentacją ustawienie stanu na componentWillMountnie spowoduje ponownego renderowania. Jeśli wywołanie AJAX nie blokuje i zwracasz Promiseaktualizację stanu składnika po pomyślnym zakończeniu, istnieje szansa, że odpowiedź nadejdzie po wyrenderowaniu składnika. Ponieważ componentWillMountnie powoduje ponownego renderowania, nie będziesz mieć oczekiwanego zachowania, jakim jest renderowany komponent z żądanymi danymi.
Jeśli użyjesz którejkolwiek z bibliotek flux, a żądane dane trafią do sklepu, do którego jest podłączony komponent (lub dziedziczą z podłączonego komponentu), nie będzie to problem, ponieważ odbiór tych danych najprawdopodobniej zmieni właściwości ostatecznie.
componentWillMountnie wyzwala ponownego renderowania tylko dlatego, że przed pierwszym renderowaniem zdefiniowano nowy stan. Ale jeśli setStatezostanie wywołana w wywołaniu zwrotnym AJAX, z całą pewnością zostanie wywołana po pierwszym renderowaniu i spowoduje ponowne renderowanie.
componentWillMount
zakończy się niepowodzeniem, biorąc pod uwagę, że komponent ... nie został zamontowany.Odpowiedzi:
componentDidMount
dotyczy skutków ubocznych. Dodawanie detektorów zdarzeń, AJAX, mutowanie DOM, itp.componentWillMount
rzadko się przydaje; szczególnie jeśli zależy Ci na renderowaniu po stronie serwera (dodanie detektorów zdarzeń powoduje błędy i wycieki oraz wiele innych rzeczy, które mogą pójść źle).Mówi się o usuwaniu
componentWillMount
z komponentów klasy, ponieważ służy to temu samemu celowi, co konstruktor. Pozostanie nacreateClass
komponentach.źródło
componentWillMount
? Naprawdę nie widzę różnicy.componentWillMount
zostanie wykonane na renderowaniu po stronie serwera. Gdybyś używał,componentDidMount
to byłby wykonywany tylko po stronie klienta. W rezultacie umieszczanie rzeczy,componentWillMount
które wykonują zewnętrzne interakcje lub są powiązane ze zdarzeniami itp., Nie jest dobrym pomysłem. Jeśli nie planujesz renderować swoich komponentów na serwerze, nadal nie jest to dobry pomysł tylko ze względu na potencjalną przenośność kodu. To wszystko jest poza głównym powodem, dla którego jest zły, co zostało wyjaśnione w odpowiedzi @daniula.Na początku też miałem ten sam problem. Postanowiłem spróbować wysyłać prośby,
componentWillMount
ale kończy się to różnymi drobnymi problemami.Wyzwalałem renderowanie, gdy połączenie Ajax zakończyło się z nowymi danymi. W pewnym momencie renderowanie komponentu zajęło więcej czasu niż uzyskanie odpowiedzi z serwera i w tym momencie wywołanie zwrotne ajax wyzwalało renderowanie na niezmontowanym komponencie. Jest to rodzaj skrajnego przypadku, ale prawdopodobnie jest ich więcej, więc bezpieczniej jest się trzymać
componentDidMount
.źródło
componentWillMount
, więc nadal powinieneś używać gocomponentDidMount
do wywołań Ajax.setState
konstruktora komponentu i nie masz możliwości określenia, kiedy wywołanie AJAX się zakończy. twitter.com/dan_abramov/status/576453138598723585Zgodnie z dokumentacją ustawienie stanu na
componentWillMount
nie spowoduje ponownego renderowania. Jeśli wywołanie AJAX nie blokuje i zwracaszPromise
aktualizację stanu składnika po pomyślnym zakończeniu, istnieje szansa, że odpowiedź nadejdzie po wyrenderowaniu składnika. PonieważcomponentWillMount
nie powoduje ponownego renderowania, nie będziesz mieć oczekiwanego zachowania, jakim jest renderowany komponent z żądanymi danymi.Jeśli użyjesz którejkolwiek z bibliotek flux, a żądane dane trafią do sklepu, do którego jest podłączony komponent (lub dziedziczą z podłączonego komponentu), nie będzie to problem, ponieważ odbiór tych danych najprawdopodobniej zmieni właściwości ostatecznie.
źródło
componentWillMount
nie wyzwala ponownego renderowania tylko dlatego, że przed pierwszym renderowaniem zdefiniowano nowy stan. Ale jeślisetState
zostanie wywołana w wywołaniu zwrotnym AJAX, z całą pewnością zostanie wywołana po pierwszym renderowaniu i spowoduje ponowne renderowanie.