I React representerer hooks en effektiv metode for å styre sideeffekter i komponenter. Blant disse, er `useEffect`, `useLayoutEffect`, og `useEffectEvent` noen av de mest brukte for å håndtere slike effekter. Det er essensielt å velge riktig hook for oppgaven, da hver av dem har sine unike bruksområder.
`useEffect`-hooken
`useEffect`-hooken er en grunnleggende del av React, som tillater utførelse av sideeffekter som manipulering av DOM, asynkrone operasjoner og datahenting i funksjonelle komponenter. Denne hooken tar to argumenter: en effektfunksjon og en avhengighetsmatrise.
Effektfunksjonen inneholder koden for sideeffekten, mens avhengighetsmatrisen definerer når effektfunksjonen skal utføres. Hvis avhengighetsmatrisen er tom, kjøres effektfunksjonen kun én gang etter den første renderingen av komponenten. Hvis ikke, utføres den hver gang noen av verdiene i avhengighetsmatrisen endres.
Her er et eksempel på hvordan man benytter `useEffect`-hooken for datahenting:
import React from "react";function App() { const [data, setData] = React.useState([]);
React.useEffect(() => { fetch("https://jsonplaceholder.typicode.com/posts") .then((response) => response.json()) .then((data) => setData(data)); }, []);
return (
{data.map((item) => (); }{item.title}))}export default App;
Dette kodeeksemplet illustrerer en applikasjonskomponent som henter data fra et eksternt API ved hjelp av `useEffect`-hooken. Effektfunksjonen henter data fra JSONPlaceholder API. Deretter analyseres JSON-responsen og den hentede dataen lagres i datatilstanden.
Med den oppdaterte datatilstanden viser applikasjonskomponenten `title`-egenskapen for hvert element i tilstanden.
Kjennetegn ved `useEffect`-hooken
- **Asynkronvennlig:** Den støtter asynkrone operasjoner, noe som gjør datahenting praktisk.
- **Kjøres etter rendering:** `useEffect`-hooken utfører effektene etter at komponenten er rendret, og sikrer at hooken ikke blokkerer brukergrensesnittet.
- **Opprydding:** Den gir en integrert måte å utføre opprydding ved å returnere en funksjon. Dette er spesielt nyttig ved arbeid med lyttere eller abonnementer.
`useLayoutEffect`-hooken
`useLayoutEffect`-hooken er lik `useEffect`, men den kjøres synkront etter alle DOM-mutasjoner. Dette betyr at den utføres før nettleseren maler skjermen. Dette gjør den egnet for oppgaver som krever presis kontroll over DOM-oppsett og stiler, som for eksempel måling av elementstørrelse, endring av størrelse på elementer eller animering av elementposisjon.
Nedenfor er et eksempel på hvordan du kan bruke `useLayoutEffect`-hooken for å endre bredden på et knappe-element:
import React from "react";function App() { const button = React.useRef();
React.useLayoutEffect(() => { const { width } = button.current.getBoundingClientRect();
button.current.style.width = `${width + 12}px`; }, []);
return (
); }export default App;
Kodeblokken ovenfor øker bredden på knappe-elementet med 12 piksler ved bruk av `useLayoutEffect`-hooken. Dette sikrer at knappebredden endres før knappen vises på skjermen.
Kjennetegn ved `useLayoutEffect`-hooken
- **Synkron:** Den kjøres synkront og kan potensielt blokkere brukergrensesnittet hvis operasjonene er tunge.
- **DOM lese/skrive:** Den er best egnet for lesing og skriving direkte til DOM, spesielt når endringene er nødvendige før nettleseren maler på nytt.
`useEffectEvent`-hooken
`useEffectEvent`-hooken er en React-hook som løser avhengighetsproblemene knyttet til `useEffect`-hooken. Hvis du er kjent med `useEffect`, vet du at avhengighetsarrayet kan være utfordrende. Noen ganger må du legge til flere verdier i avhengighetsmatrisen enn det som er strengt nødvendig.
For eksempel:
import React from "react";function App() { const connect = (url) => { };
const logConnection = (message, loginOptions) => { };
const onConnected = (url, loginOptions) => { logConnection(`Connected to ${url}`, loginOptions); };
React.useEffect(() => { const device = connect(url); device.onConnected(() => { onConnected(url); });
return () => { device.disconnect(); }; }, [url, onConnected]);
return
; }export default App;
Denne koden viser en applikasjonskomponent som administrerer en tilkobling til en ekstern tjeneste. `connect`-funksjonen kobler til en spesifisert URL, mens `logConnection`-funksjonen logger tilkoblingsdetaljene. Til slutt kaller `onConnected`-funksjonen `logConnection`-funksjonen for å logge en melding om vellykket tilkobling når enheten kobler seg til.
`useEffect`-hooken kaller `connect`-funksjonen og setter deretter opp en `onConnected`-tilbakekallingsfunksjon som skal utføres når enheten utløser `onConnected`-hendelsen. Denne tilbakekallingsfunksjonen logger en tilkoblingsmelding. Den returnerer en oppryddingsfunksjon som aktiveres når komponenten demonteres. Denne funksjonen er ansvarlig for å koble fra enheten.
Avhengighetsmatrisen inneholder `url`-variabelen og `onConnected`-funksjonen. Applikasjonskomponenten vil opprette `onConnected`-funksjonen ved hver rendering. Dette fører til at `useEffect`-funksjonen kjører i en sløyfe, som igjen vil fortsette å rendre applikasjonskomponenten på nytt.
Det er flere måter å løse `useEffect`-sløyfeproblemet på. Likevel er den mest effektive måten uten å legge til unødvendige verdier i avhengighetsmatrisen, å bruke `useEffectEvent`-hooken.
import React from "react";function App() { const connect = (url) => { };
const logConnection = (message, loginOptions) => { };
const onConnected = React.useEffectEvent((url, loginOptions) => { logConnection(`Connected to ${url}`, loginOptions); });
React.useEffect(() => { const device = connect(url); device.onConnected(() => { onConnected(url); });
return () => { device.disconnect(); }; }, [url]);
return
; } export default App;
Ved å pakke `onConnected`-funksjonen med `useEffectEvent`-hooken, kan `useEffectEvent` alltid lese de nyeste verdiene for `message`- og `loginOptions`-parametere før de sendes til `useEffect`-hooken. Dette betyr at `useEffect` ikke trenger å stole på `onConnected`-funksjonen eller verdiene som sendes til den.
`useEffectEvent`-hooken er nyttig når du vil at `useEffect` skal være avhengig av en bestemt verdi, selv om effekten utløser en hendelse som krever andre verdier du foretrekker å ikke bruke som avhengigheter i `useEffect`.
Kjennetegn ved `useEffectEvent`-hooken
- Den er best egnet for hendelsesdrevne sideeffekter.
- `useEffectEvent`-hooken fungerer ikke med hendelsesbehandlere som `onClick`, `onChange`, etc.
`useEffectEvent`-hooken er fortsatt eksperimentell og ikke tilgjengelig i React versjon 18-hooks.
Når skal du bruke hvilken hook?
Hver av de ovennevnte hooks for datahenting passer for forskjellige situasjoner:
- **Datahenting:** `useEffect` er et utmerket valg.
- **Direkte DOM-manipulasjon:** Hvis du trenger å gjøre synkrone endringer i DOM før en ny maling, velg `useLayoutEffect`.
- **Lettvektsoperasjoner:** For operasjoner som ikke risikerer å blokkere brukergrensesnittet, kan du fritt bruke `useEffect`.
- **Hendelsesdrevne sideeffekter:** Bruk `useEffectEvent`-hooken for å pakke inn hendelser, og `useEffect`-hooken for å kjøre sideeffektene.
Håndter sideeffekter effektivt
React-hooks åpner opp for en rekke muligheter, og forståelsen av forskjellen mellom `useEffect`, `useLayoutEffect` og `useEffectEvent` kan ha stor betydning for hvordan du håndterer sideeffekter og DOM-manipulasjon. Det er viktig å vurdere disse hooksenes spesifikke krav og implikasjoner for å skape brukervennlige applikasjoner.