Nie można używać żadnego z istniejących metod cyklu życia ( componentDidMount
, componentDidUpdate
, componentWillUnmount
itd) w haku. Mogą być używane tylko w komponentach klasy. A z hakami można używać tylko w elementach funkcjonalnych. Poniższy wiersz pochodzi z dokumentu React:
Jeśli jesteś zaznajomiony z React metod klasy cyklu życia, można myśleć useEffect
Hook jak componentDidMount
, componentDidUpdate
i componentWillUnmount
łączone.
Sugeruje to, że możesz naśladować tę metodę cyklu życia z komponentu klasy w komponentach funkcjonalnych.
Kod wewnątrz jest componentDidMount
uruchamiany raz po zamontowaniu komponentu. useEffect
odpowiednikiem haka dla tego zachowania jest
useEffect(() => {
// Your code here
}, []);
Zwróć uwagę na drugi parametr (pusta tablica). To będzie działać tylko raz.
Bez drugiego parametruuseEffect
hak zostanie wywołana na każdy render składnika, które mogą być niebezpieczne.
useEffect(() => {
// Your code here
});
componentWillUnmount
służy do czyszczenia (np. usuwanie detektorów zdarzeń, anulowanie licznika czasu itp.). Załóżmy, że dodajesz odbiornik zdarzeń componentDidMount
i usuwasz go, componentWillUnmount
jak poniżej.
componentDidMount() {
window.addEventListener('mousemove', () => {})
}
componentWillUnmount() {
window.removeEventListener('mousemove', () => {})
}
Hook odpowiednik powyższego kodu będzie następujący
useEffect(() => {
window.addEventListener('mousemove', () => {});
// returned function will be called on component unmount
return () => {
window.removeEventListener('mousemove', () => {})
}
}, [])
useEffect()
funkcję, dzięki.componentWillMount
componentWillMount
, niecomponentWillUnmount
. Ta odpowiedź rzeczywiście w ogóle nie odpowiada na pytanie, a jedynie powtórzyła to, co PO już sugerował, aby wiedzieć.useComponentDidMount hook
W większości przypadków
useComponentDidMount
jest to narzędzie, którego należy użyć. Uruchomi się tylko raz, po zamontowaniu komponentu (wstępnym renderowaniu).useComponentWillMount
Należy zauważyć, że w klasach komponenty
componentWillMount
są uważane za starsze. Jeśli chcesz, aby kod działał tylko raz przed zamontowaniem komponentu, możesz użyć konstruktora. Więcej o tym tutaj . Ponieważ komponent funkcjonalny nie ma odpowiednika konstruktora, użycie haka do uruchomienia kodu tylko raz przed zamontowaniem komponentu może mieć sens w niektórych przypadkach. Możesz to osiągnąć dzięki niestandardowemu haczykowi.Istnieje jednak pułapka. Nie używaj go do asynchronicznego ustawiania swojego stanu (np. Po żądaniu serwera. Jak można się spodziewać, wpłynie to na początkowe renderowanie, którego nie będzie). W takich przypadkach należy się zająć
useComponentDidMount
.Próbny
Pełne demo
źródło
componentWillMount
oparciu ouseEffect
ma dwa problemy. Po pierwsze, nie ma cyklu życia komponentów funkcjonalnych, oba zaczepy będą działać po wyrenderowaniu komponentu, więcRuns only once before component mounts
jest to mylące. DrugicomponentWillMount
jest wywoływany podczas renderowania na serwerze iuseEffect
nie jest. Wiele bibliotek nadal polega na tym,UNSAFE_componentWillMount
ponieważ obecnie jest to jedyny sposób na wywołanie efektu ubocznego po stronie serwera.Jak podaje reactjs.org, w przyszłości składnik componentWillMount nie będzie obsługiwany. https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
Nie ma potrzeby używania elementu componentWillMount.
Jeśli chcesz coś zrobić przed zamontowaniem komponentu, po prostu zrób to w konstruktorze ().
Jeśli chcesz wykonywać żądania sieciowe, nie rób tego w componentWillMount. Dzieje się tak, ponieważ spowoduje to nieoczekiwane błędy.
Żądania sieciowe można wykonać w module componentDidMount.
Mam nadzieję, że to pomoże.
zaktualizowano 08.03.2019 r
Powodem, dla którego pytasz o componentWillMount, jest prawdopodobnie to, że chcesz zainicjować stan przed renderowaniem.
Po prostu zrób to w useState.
a może chcesz uruchomić funkcję w componentWillMount, na przykład, jeśli twój oryginalny kod wygląda tak:
z hakiem wszystko, co musisz zrobić, to usunąć metodę cyklu życia:
Chcę tylko dodać coś do pierwszej odpowiedzi na temat useEffect.
useEffect działa na każdym renderowaniu, jest połączeniem składników componentDidUpdate, componentDidMount i ComponentWillUnmount.
Jeśli dodamy pustą tablicę w useEffect, będzie ona działać tylko wtedy, gdy komponent zostanie zamontowany. Dzieje się tak, ponieważ useEffect porówna przekazaną do niego tablicę. Więc nie musi to być pusta tablica, może to być tablica, która się nie zmienia. Na przykład może to być [1,2,3] lub ['1,2']. useEffect nadal działa tylko po zamontowaniu komponentu.
To zależy od Ciebie, czy chcesz, aby był uruchamiany tylko raz, czy po każdym renderowaniu. Nie jest niebezpieczne, jeśli zapomnisz dodać tablicę, o ile wiesz, co robisz.
Stworzyłem próbkę do haka. Proszę sprawdź to.
https://codesandbox.io/s/kw6xj153wr
aktualizacja 21.08.2019 r
Odkąd napisałem powyższą odpowiedź była biała. Myślę, że jest coś, na co musisz zwrócić uwagę. Kiedy używasz
Kiedy reakcja porównuje wartości przekazane do tablicy [], używa Object.is () do porównania. Jeśli przekażesz mu obiekt, taki jak
To jest dokładnie to samo, co:
Wyrenderuje się ponownie za każdym razem, ponieważ gdy Object.is () porównuje obiekt, porównuje jego odwołanie, a nie samą wartość. To jest to samo, dlaczego {} === {} zwraca fałsz, ponieważ ich odwołania są różne. Jeśli nadal chcesz porównać sam obiekt, a nie odniesienie, możesz zrobić coś takiego:
źródło
useLayoutEffect
można to osiągnąć z pustym zestawem obserwatorów ([]
), jeśli funkcjonalność jest w rzeczywistości podobna docomponentWillMount
- będzie działać, zanim pierwsza treść dotrze do DOM - chociaż faktycznie są dwie aktualizacje, ale są one synchroniczne przed rysowaniem na ekranie.na przykład:
Korzyść w porównaniu
useState
z inicjatorem / ustawiaczem lubuseEffect
polega na tym, że może obliczyć przepustkę renderowania, nie ma rzeczywistych ponownych renderów do DOM, które użytkownik zauważy, i jest uruchamiany przed pierwszym zauważalnym renderowaniem, co nie ma miejsca w przypadkuuseEffect
. Wadą jest oczywiście niewielkie opóźnienie w pierwszym renderowaniu, ponieważ przed malowaniem na ekran musi nastąpić sprawdzenie / aktualizacja. Jednak to naprawdę zależy od twojego przypadku użycia.Osobiście uważam, że
useMemo
jest w porządku w niektórych niszowych przypadkach, w których musisz zrobić coś ciężkiego - o ile pamiętasz, że jest to wyjątek od normy.źródło
Oto sposób, w jaki symuluję konstruktora w komponentach funkcjonalnych za pomocą
useRef
hooka:Oto przykład cyklu życia:
Oczywiście komponenty klas nie mają
Body
kroków, nie jest możliwe wykonanie symulacji 1: 1 ze względu na różne koncepcje funkcji i klas.źródło
Napisałem niestandardowy punkt zaczepienia, który uruchomi funkcję raz przed pierwszym renderowaniem.
useBeforeFirstRender.js
Stosowanie:
źródło
Jest ładny obejście do wdrożenia
componentDidMount
icomponentWillUnmount
zuseEffect
.Na podstawie dokumentacji
useEffect
może zwrócić funkcję „czyszczenia”. ta funkcja nie będzie wywoływana przy pierwszymuseEffect
wywołaniu, tylko przy kolejnych.Dlatego jeśli użyjemy
useEffect
zaczepu bez żadnych zależności, zaczep zostanie wywołany tylko wtedy, gdy komponent jest zamontowany, a funkcja "czyszczenia" jest wywoływana, gdy komponent jest odmontowywany.Wywołanie funkcji powrotu oczyszczania jest wywoływane tylko wtedy, gdy komponent jest odmontowany.
Mam nadzieję że to pomoże.
źródło
useEffect
rozmowy można dostać taką samą funkcjonalnośćcomponentWillMount
icomponentWillUnmount
w ładnym i czystym sposóbuseEffect
działa tylko po renderowaniu, podczas gdycomponentWillMount
działa przed renderowaniem składnika.componentDidMount
niecomponentWillMount
. Brakowało mi tego w pytaniu, moja wina.Możesz zhakować hak useMemo, aby naśladować zdarzenie cyklu życia componentWillMount. Po prostu zrób:
Musiałbyś zachować punkt zaczepienia useMemo, zanim cokolwiek wchodzi w interakcję z twoim stanem. Nie jest to zamierzone, ale działało w przypadku wszystkich problemów z komponentem WillMount.
To działa, ponieważ useMemo nie wymaga zwracania wartości i nie musisz jej używać jako czegokolwiek, ale ponieważ zapamiętuje wartość na podstawie zależności, które będą uruchamiane tylko raz ("[]") i są na wierzchu naszego komponentu uruchamia się raz, gdy komponent zostanie zamontowany przed czymkolwiek innym.
źródło
https://reactjs.org/docs/hooks-reference.html#usememo
źródło
Odpowiedź Bena Karpa wydaje mi się jedyną słuszną.
Ale ponieważ używamy funkcjonalnych sposobów, tylko inne podejście może przynieść korzyści z zamknięcia i HoC:
Następnie użyj go:
źródło
Krótka odpowiedź na Twoje pierwotne pytanie, w jaki sposób
componentWillMount
można ich używać z hakami React:componentWillMount
jest przestarzała i uważane dziedzictwo . Reaguj rekomendację :Teraz w Hook FAQ dowiesz się, jaki jest odpowiednik konstruktora klasy dla komponentów funkcji:
Tak więc przykład użycia
componentWillMount
wygląda następująco:źródło
Po prostu dodaj pustą tablicę zależności w useEffect, będzie działać jak
componentDidMount
.źródło
Jest prosta sztuczka, aby zasymulować
componentDidMount
icomponentWillUnmount
używającuseEffect
:źródło