0Pricing
React Academy · Lekcja

Pomiar elementów DOM za pomocą useLayoutEffect

Odczytywać wymiary, pozycje i przesunięcia przewijania elementów po ułożeniu, ale przed rysowaniem, aby uniknąć migotania

Pomiar elementów DOM za pomocą useLayoutEffect to bezpłatna lekcja React Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.

Omówienie getBoundingClientRect

element.getBoundingClientRect() zwraca obiekt DOMRect zawierający rozmiar i położenie elementu względem obszaru widoku: top, right, bottom, left, width i height. Aby zwrócić dokładne wartości, wymusza wykonanie obliczeń layoutu przez przeglądarkę, dlatego wywołuj go oszczędnie.

Problem z odczytem w useEffect

Jeśli odczytasz getBoundingClientRect() w useEffect, przeglądarka zdążyła już wykonać malowanie. Jeśli następnie ustawisz stan na podstawie pomiaru, React ponownie wyrenderuje komponent, a przeglądarka wykona kolejne malowanie. Użytkownik może przez chwilę widzieć element w niewłaściwym położeniu lub rozmiarze, zanim korekta pojawi się podczas drugiego malowania.

Dlaczego useLayoutEffect rozwiązuje ten problem

Odczyt pomiarów w useLayoutEffect odbywa się po mutacjach DOM, ale przed malowaniem. Każda aktualizacja stanu wywołana przez pomiar powoduje synchroniczne ponowne renderowanie i zatwierdzenie poprawionego DOM przez React — wszystko to przed namalowaniem czegokolwiek przez przeglądarkę. Użytkownik widzi tylko końcowy, prawidłowy wynik w jednym cyklu malowania.

Pozycjonowanie dymka

Dymek powinien pojawić się w pobliżu elementu, który go wywołał. Zmierz położenie tego elementu w useLayoutEffect za pomocą getBoundingClientRect(), oblicz bezwzględne położenie dymka i zapisz je w stanie. Dymek zostanie wyrenderowany we właściwym miejscu już podczas pierwszego malowania, bez widocznego przeskoku z nieprawidłowego położenia początkowego.

Animowanie elementu: odczytywanie początkowego rozmiaru

Aby animować element od jego naturalnego (nieograniczonego) rozmiaru do stałego rozmiaru, trzeba znać jego naturalny rozmiar przed zastosowaniem ograniczenia. Odczytaj wysokość elementu w useLayoutEffect, zanim zostanie zastosowany jakikolwiek styl animacji, zapisz ją w stanie, a następnie użyj jej jako początkowej wartości klatki kluczowej przejścia CSS.

Wysokość przyklejonego nagłówka

Gdy strona ma przyklejony nagłówek, treść powinna mieć górny padding równy wysokości nagłówka, aby nie była za nim ukryta. Zmierz wysokość nagłówka w useLayoutEffect za pomocą ref: headerRef.current.getBoundingClientRect().height. Ustaw tę wartość jako paddingTop kontenera treści. Układ będzie prawidłowy już podczas pierwszego renderowania.

Aktualizacja stanu powoduje synchroniczne ponowne renderowanie

Gdy wywołasz setState wewnątrz useLayoutEffect, React natychmiast uruchomi kolejny cykl renderowania i commitowania w tym samym synchronicznym bloku. To ponowne renderowanie również uruchomi useLayoutEffect. Uważaj, aby nie utworzyć nieskończonej pętli: aktualizuj stan tylko wtedy, gdy nowy pomiar różni się od bieżącej wartości stanu.

SSR: pomiary zwracają zero

Na serwerze elementy DOM nie istnieją, więc getBoundingClientRect() może zgłosić wyjątek lub zwrócić zera. Zabezpiecz useLayoutEffect za pomocą sprawdzenia: if (typeof window === 'undefined') return;. W aplikacjach SSR może być konieczne nawodnienie z użyciem zastępczego rozmiaru, a następnie wykonanie pomiaru po nawodnieniu po stronie klienta.

ResizeObserver do ciągłego śledzenia

Jednorazowy pomiar za pomocą useLayoutEffect zapewnia rozmiar w momencie montowania. Do śledzenia zmian rozmiaru podczas zmieniania rozmiaru elementu, na przykład w wyniku zmiany rozmiaru okna, dynamicznej treści lub zmian CSS, użyj zamiast tego ResizeObserver. Wywołuje on funkcję zwrotną za każdym razem, gdy rozmiar elementu się zmieni, dzięki czemu lepiej nadaje się do responsywnych komponentów.

Unikanie zbędnych pomiarów

Jeśli kilka efektów potrzebuje tego samego pomiaru, oblicz go raz i udostępnij za pomocą kontekstu albo przekaż jako props. Obliczanie tej samej wartości getBoundingClientRect() w wielu wywołaniach useLayoutEffect powoduje wiele synchronicznych odczytów layoutu, z których każdy jest stosunkowo kosztowny. W miarę możliwości łącz pomiary.

Czas ustawienia ref względem useLayoutEffect

Ref są uzupełniane przed uruchomieniem efektów. Gdy uruchamiany jest useLayoutEffect, masz gwarancję, że ref.current wskazuje element DOM. Dlatego ten schemat działa: useLayoutEffect(() => { const rect = ref.current.getBoundingClientRect(); ... }, []). W efekcie layoutu zamontowanego komponentu ref nigdy nie ma wartości null.

Czas uruchamiania getBoundingClientRect

Dlaczego lepiej wywoływać getBoundingClientRect() w useLayoutEffect niż w useEffect?

Podsumowanie lekcji: mierzenie elementów DOM

Używaj getBoundingClientRect() w useLayoutEffect, aby odczytywać pomiary DOM po mutacjach, ale przed malowaniem. Aktualizacje stanu wynikające z tych pomiarów powodują synchroniczne ponowne renderowanie uwzględniane w tym samym malowaniu, co zapobiega migotaniu. Zabezpiecz kod przed SSR za pomocą sprawdzenia typeof window. Do ciągłego śledzenia zmian rozmiaru wybieraj ResizeObserver.

Często zadawane pytania

Czy lekcja „Pomiar elementów DOM za pomocą useLayoutEffect” jest bezpłatna?

Tak — pełny tekst „Pomiar elementów DOM za pomocą useLayoutEffect” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pomiar elementów DOM za pomocą useLayoutEffect”?

Odczytywać wymiary, pozycje i przesunięcia przewijania elementów po ułożeniu, ale przed rysowaniem, aby uniknąć migotania Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć React Academy?

Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Pomiar elementów DOM za pomocą useLayoutEffect”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?

Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Faza renderowania i zatwierdzanie DOM
  2. Kiedy uruchamia się useLayoutEffect, a kiedy useEffect
  3. Pomiar elementów DOM za pomocą useLayoutEffect
  4. Unikanie przeciążenia layoutu i migotania wizualnego
← Powrót do React Academy