React Academy · Lektion

Mäta DOM-element med useLayoutEffect

Läs elementens mått, positioner och rullningsförskjutningar efter layouten men före målningen för att undvika flimmer.

Lektion 3 av 413 steg

Mäta DOM-element med useLayoutEffect är en gratis lektion i React Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för React Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i React Academy innehåller totalt 4 lektioner.

Översikt över getBoundingClientRect

element.getBoundingClientRect() returnerar ett DOMRect-objekt med elementets storlek och position i förhållande till viewporten: top, right, bottom, left, width och height. Det tvingar webbläsaren att utföra en layoutberäkning för att returnera korrekta värden, så anropa det sparsamt.

Problemet med att läsa i useEffect

Om du läser av getBoundingClientRect() i en useEffect har webbläsaren redan målat. Om du sedan uppdaterar tillståndet utifrån mätningen renderar React om komponenten och webbläsaren målar igen. Användaren kan kortvarigt se elementet på fel position eller med fel storlek innan korrigeringen visas i den andra målningen.

Därför löser useLayoutEffect detta

Avläsning av mätvärden i useLayoutEffect sker efter DOM-mutationer men före målning. Alla tillståndsuppdateringar som utlöses av mätningen får React att rendera om synkront och genomföra den korrigerade DOM:en — allt innan webbläsaren har målat något. Användaren ser bara det slutliga, korrekta resultatet i en enda målningscykel.

Positionering av verktygstips

Ett verktygstips behöver visas nära elementet som utlöser det. Mät det utlösande elementets position i useLayoutEffect med hjälp av getBoundingClientRect(), beräkna verktygstipsets absoluta position och spara positionen i tillståndet. Verktygstipset renderas på rätt plats redan vid den första målningen, utan något synligt hopp från en felaktig ursprunglig position.

Elementanimering: läsa av ursprunglig storlek

För att animera ett element från dess naturliga, obegränsade storlek till en fast storlek måste du känna till den naturliga storleken innan begränsningen tillämpas. Läs av elementets höjd i useLayoutEffect innan någon animeringsstil tillämpas, spara den i tillståndet och använd den sedan som startvärde för keyframen i din CSS-övergång.

Höjd på sticky header

När en sida har en sticky header behöver innehållet ha en övre utfyllnad som motsvarar headerns höjd för att undvika att döljas bakom den. Mät headerns höjd i useLayoutEffect med hjälp av en ref: headerRef.current.getBoundingClientRect().height. Ange detta som paddingTop på innehållsbehållaren. Layouten är korrekt redan vid den första renderingen.

Tillståndsuppdatering orsakar synkron omrendering

När du anropar setState inuti useLayoutEffect kör React omedelbart en ny renderings- och commitcykel i samma synkrona arbetsblock. Denna omrendering kör också komponentens useLayoutEffect. Var försiktig så att du inte skapar en oändlig loop: uppdatera endast tillståndet om det nya mätvärdet skiljer sig från det aktuella tillståndsvärdet.

SSR: mätningar returnerar noll

På servern finns inga DOM-element, så getBoundingClientRect() skulle kasta ett fel eller returnera nollvärden. Skydda din useLayoutEffect med en kontroll: if (typeof window === 'undefined') return;. I SSR-appar kan du behöva hydrera med en platshållarstorlek och mäta efter hydreringen på klienten.

ResizeObserver för löpande övervakning

En engångsmätning med useLayoutEffect ger dig storleken vid montering. Om du vill följa storleksändringar när elementet ändrar storlek på grund av fönsterändringar, dynamiskt innehåll eller CSS-ändringar använder du i stället ResizeObserver. Den anropar en callback varje gång elementets storlek ändras, vilket gör den mer lämplig för responsiva komponenter.

Undvika överflödiga mätningar

Om flera effekter behöver samma mätvärde beräknar du det en gång och delar det via context eller skickar ned det som props. Om samma getBoundingClientRect()-värde beräknas i flera useLayoutEffect-anrop utlöses flera synkrona layoutavläsningar, som var och en är relativt kostsam. Samordna mätningarna när det är möjligt.

Tidpunkt för ref med useLayoutEffect

Refs fylls i innan effekter körs. När useLayoutEffect körs är det garanterat att ref.current pekar på DOM-elementet. Därför fungerar mönstret: useLayoutEffect(() => { const rect = ref.current.getBoundingClientRect(); ... }, []). En ref är aldrig null inuti en layouteffekt på en monterad komponent.

Tidpunkt för getBoundingClientRect

Varför är det bättre att anropa getBoundingClientRect() i useLayoutEffect än i useEffect?

Lektionssammanfattning: mäta DOM-element

Använd getBoundingClientRect() i useLayoutEffect för att läsa av DOM-mätningar efter mutationer men före målning. Tillståndsuppdateringar från dessa mätningar orsakar en synkron omrendering som inkluderas i samma målning och förhindrar flimmer. Skydda mot SSR med en kontroll av typeof window. För löpande storleksövervakning bör du använda ResizeObserver.

Gratis att börja

Lär dig React med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
88
Lektioner
324

Vanliga frågor

Är lektionen ”Mäta DOM-element med useLayoutEffect” gratis?

Ja – hela texten till ”Mäta DOM-element med useLayoutEffect” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i React Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i React Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Mäta DOM-element med useLayoutEffect”?

Läs elementens mått, positioner och rullningsförskjutningar efter layouten men före målningen för att undvika flimmer. Ni övar på React Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig React Academy?

Du behöver inga förkunskaper. Utbildningen i React Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Mäta DOM-element med useLayoutEffect”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här React Academy-lektionen?

Ja. Varje React Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Renderingsfasen och DOM-commit
  2. När useLayoutEffect körs jämfört med useEffect
  3. Mäta DOM-element med useLayoutEffect
  4. Undvika layout thrashing och visuellt flimmer
← Tillbaka till React Academy