Spis treści
Wprowadzenie
UseEffect
to jeden z najczęściej używanych hooków, za pomocą których uzyskujemy efekty podobne jak kiedyś za pomocą metod componentDidMount
, componentDidUpdate
i componentWillMount
. Hook ten jednak wywołuje się po przerysowaniu komponentu. Rzeczy dziejące się w hooku są asynchroniczne w stosunku do rysowania elementów na ekranie i go nie blokują.
Istnieje jednak również hook useLayoutEffect – wykonywany przed przerysowaniem elementu, blokujące aktualizację tego co widzi użytkownik. Jak się okazuje, są przypadki gdy takie zachowanie jest nam potrzebne – mimo że w większości przypadków wystarczy nam useEffect
.
Zapraszam Cię więc do artykułu, w którym przedstawię taki przypadek – luźno bazujący na tym, co niedawno przydarzyło mi się w pracy.
Przechodzenie dalej bez kliknięcia
Opis przypadku
Łatwo wyobrazić sobie sytuację, gdy mamy np duży formularz składający się z kilku kroków i część danych może być dostępna zanim użytkownik je wypełni – np jest to formularz zamówienia jedzenia i przy poprzednich zamówieniach podał on już adres który został zapisany w localStorage.
Możemy więc chcieć pominąć krok jeżeli już mamy do niego dane.
Implementacja useEffect vs useLayoutEffect
Załóżmy, że mamy listę kroków od 1 do X i chcemy pominąć krok 3. Komponent Step
to informacja na którym kroku jesteśmy oraz możliwość przejścia dalej:
Przygotujmy 2 implementacje pomijania kroku – pierwszą z useEffect
i drugą z useLayoutEffect
, wyglądające niemal bliźniaczo:
Czyli zamiast czekać aż użytkownik kliknie, na kroku który chcemy pominąć „klikamy” automatycznie za niego. Rezultat uruchomienia wygląda tak:

Przy zwyczajnym klikaniu różnica jest niezauważalna – oba przykłady po prostu pomijają krok 3.
Co jednak się stanie gdy spowolnimy działanie aplikacji? W zakładce Performance w DevTools możemy zasymulować słabszy komputer zmieniając ustawienia opóźnienia CPU:

Spowolnienie to spowoduje pojawienie się różnicy:
- Wersja
useLayoutEffect
zachowuje się po staremu, krok 3 jest pomijany - Wersja z
useEffect
pokazuje na chwilę krok 3 po potem przeskoczyć do kroku 4. To dlatego, że akcja pominięcia kroku wykonuje się po przerysowaniu – krok 3 jest wyświetlony użytkownikowi na ekranie a dopiero potem pojawia się akcja która powoduje pominięcie.
Kod przykładu na Github
Pełny kod przykładu znajdziesz pod adresem:
https://github.com/radek-anuszewski/use-layout-hook-demo
Klikalny przykład na Github Pages
Przykład który możesz poklikać znajduje się pod adresem:
https://radek-anuszewski.github.io/use-layout-hook-demo/
Podsumowanie
Jak się okazuje, nawet jak pozornie dziwna konstrukcja jak hook useLayoutEffect
znajduje swoje zastosowanie w praktyce – może być ratunkiem w sytuacji, gdy nie ma czasu bądź możliwości na kompleksowe zmiany by pozbyć się problemu w lepszy i ładniejszy sposób. Pierwszym wyborem podczas codziennej pracy powinien być jednak useEffect
, który nie blokuje rysowania UI.