React Native Academy · Lektion

useEffect-hooket og afhængighedsarrays

Forstå, hvornår useEffect kører, styr det med et afhængighedsarray, og ryd abonnementer eller timere op ved at returnere en oprydningsfunktion.

Lektion 1 af 413 trin

useEffect-hooket og afhængighedsarrays er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad er useEffect?

useEffect gør det muligt for funktionskomponenter at udføre bivirkninger: hente data, oprette abonnementer, manipulere DOM'en, starte timere eller kalde native API'er. Bivirkninger må ikke køres direkte i renderingsfunktionen, fordi rendering skal være ren. useEffect kører efter, at komponenten er renderet på skærmen.

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    console.log('Component rendered');
    // Side effects go here
  });
}

Afhængighedsarrayet

Det andet argument til useEffect er afhængighedsarrayet. React bruger det til at afgøre, hvornår effekten skal køres igen. Hvis afhængighedsarrayet udelades, kører effekten efter hver rendering. Hvis det er tomt ([]), kører effekten én gang efter den første rendering. Hvis det indeholder værdier, køres effekten igen, hver gang en af værdierne ændres.

// Runs after every render
useEffect(() => { ... });

// Runs once on mount
useEffect(() => { ... }, []);

// Runs on mount and whenever userId changes
useEffect(() => { ... }, [userId]);

Hentning af data ved montering

Det mest almindelige useEffect-mønster er at hente data, når en komponent monteres første gang. Send et tomt afhængighedsarray med for at sikre, at hentningen kører præcis én gang. Gem resultatet i tilstanden, og render det i JSX. React kalder effekten efter den første visning, så komponenten renderes først én gang med en tom eller indlæsningsbaseret tilstand, før dataene ankommer.

function PostsScreen() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((res) => res.json())
      .then((data) => setPosts(data));
  }, []); // empty array = run once on mount

  return <FlatList data={posts} ... />;
}

Reaktive afhængigheder

Når du vil have effekten til at køre igen, hver gang en værdi ændres, f.eks. en søgeforespørgsel eller et bruger-id, skal du angive værdien i afhængighedsarrayet. React sammenligner hver afhængighed med dens tidligere værdi efter hver rendering, og hvis nogen af dem er ændret, kører React effekten igen. Det skaber et reaktivt dataflow: brugerfladehændelse → opdatering af tilstand → effekten kører igen.

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch('/api/users/' + userId)
      .then((res) => res.json())
      .then((data) => setUser(data));
  }, [userId]); // re-fetch whenever userId changes

  if (!user) return <ActivityIndicator />;
  return <Text>{user.name}</Text>;
}

Oprydningsfunktionen

Returnér en funktion fra din effekt for at udføre oprydning. React kalder denne oprydningsfunktion, før effekten køres igen (når afhængigheder ændres), og når komponenten afmonteres. Brug den til at annullere abonnementer, rydde timere eller afbryde henteanmodninger for at forhindre hukommelseslækager og opdateringer af tilstanden på komponenter, der er afmonteret.

useEffect(() => {
  const timer = setInterval(() => {
    setTime(Date.now());
  }, 1000);

  return () => clearInterval(timer); // cleanup on unmount or re-run
}, []);

Annullering af henteanmodninger med AbortController

Når en komponent afmonteres, før en hentning er fuldført, advarer React om en opdatering af tilstanden på en afmonteret komponent. Brug AbortController til at annullere den igangværende hentning i oprydningsfunktionen. Hvis du fanger afbrydelsesfejlen (som er en AbortError), forhindrer du, at den logges som en uventet fejl.

useEffect(() => {
  const controller = new AbortController();

  fetch('/api/data', { signal: controller.signal })
    .then((res) => res.json())
    .then((data) => setData(data))
    .catch((err) => {
      if (err.name !== 'AbortError') setError(err);
    });

  return () => controller.abort();
}, []);

Kørsel af kode kun ved afmontering

Hvis du vil køre kode kun, når komponenten afmonteres, f.eks. for at afmelde en hændelseslytter, skal du returnere en oprydningsfunktion fra en useEffect med et tomt afhængighedsarray. React kalder kun oprydningen, når komponenten forlader træet, aldrig ved efterfølgende renderinger.

useEffect(() => {
  const subscription = eventEmitter.addListener('change', handler);

  return () => {
    subscription.remove(); // only on unmount
  };
}, []); // empty array = mount-only effect

Flere useEffect-kald

Du kan og bør bruge flere useEffect-kald i én komponent — ét for hver uafhængig bivirkning. React kører dem i den rækkefølge, de står i, efter hver rendering. Når effekter holdes adskilt efter ansvarsområde, bliver koden nemmere at læse, og du undgår komplekse afhængighedsarrays, der blander ikke-relateret logik.

// Effect 1: fetch user data
useEffect(() => {
  fetchUser(userId).then(setUser);
}, [userId]);

// Effect 2: analytics page view
useEffect(() => {
  analytics.logScreenView('Profile');
}, []);

// Effect 3: sync title to header
useEffect(() => {
  navigation.setOptions({ title: user?.name ?? 'Profile' });
}, [user, navigation]);

Problemer med afhængigheder: manglende afhængigheder

En almindelig fejl er at udelade en afhængighed fra arrayet. Effekten fastholder en forældet værdi for den manglende afhængighed og kører med forældede data. Medtag altid alle værdier fra komponentens omfang, som læses inde i effekten. ESLints regel react-hooks/exhaustive-deps fanger automatisk disse fejl.

// Bug: fetchUser uses userId but it is not in deps
// If userId changes, the effect still runs with the old userId
useEffect(() => {
  fetchUser(userId).then(setUser);
}, []); // Missing userId!

// Correct:
useEffect(() => {
  fetchUser(userId).then(setUser);
}, [userId]);

Undgåelse af uendelige løkker

Hvis din effekt opdaterer en tilstand, der også står angivet som en afhængighed, får du en uendelig løkke: gengivelse → effekt → tilstandsopdatering → gengivelse → effekt → .... Undgå dette med en betingelse inde i effekten, eller omstrukturer koden, så effekten ikke udløser den tilstandsopdatering, der fik den til at køre.

// Infinite loop: effect updates 'count' which is in deps
useEffect(() => {
  setCount(count + 1); // triggers re-render → effect runs again
}, [count]);

// Fix: use functional updater — no need to list count as dep
useEffect(() => {
  setCount((c) => c + 1);
}, []); // only runs once

Sammenligning af effekter med livscyklusmetoder

useEffect erstatter alle tre klassiske livscyklusmetoder for klassekomponenter: componentDidMount (tomt afhængighedsarray), componentDidUpdate (med afhængigheder) og componentWillUnmount (oprydningsfunktion). Én hook håndterer alle tre faser, så relateret logik holdes samlet i stedet for at være spredt over tre separate metoder.

useEffect(() => {
  // componentDidMount equivalent — fetch initial data
  fetchData();

  return () => {
    // componentWillUnmount equivalent — cancel subscriptions
    cancelSubscription();
  };
}, []); // runs once on mount, cleanup on unmount

Hurtigt tjek

Test din forståelse af useEffect-hooket og afhængighedsarrays fra denne lektion.

Opsummering af lektionen

I denne lektion lærte du, at useEffect kører sideeffekter efter gengivelse, at afhængighedsarrayet styrer, hvornår effekten kører igen — tomt betyder én gang ved montering, og at du skal returnere en oprydningsfunktion for at annullere abonnementer, timere og henteforespørgsler ved afmontering. Næste gang laver vi GET-forespørgsler med Axios inde i useEffect.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “useEffect-hooket og afhængighedsarrays” gratis?

Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “useEffect-hooket og afhængighedsarrays”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “useEffect-hooket og afhængighedsarrays”?

Forstå, hvornår useEffect kører, styr det med et afhængighedsarray, og ryd abonnementer eller timere op ved at returnere en oprydningsfunktion. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på React Native Academy?

Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “useEffect-hooket og afhængighedsarrays”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne React Native Academy-lektion?

Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. useEffect-hooket og afhængighedsarrays
  2. GET-requests med Axios
  3. Håndtering af indlæsnings- og fejltilstande
  4. POST, PUT og DELETE med Axios
← Tilbage til React Native Academy