Reageerhaken useEffect_


Met de useEffectHook kunt u bijwerkingen in uw componenten uitvoeren.

Enkele voorbeelden van bijwerkingen zijn: het ophalen van gegevens, het direct bijwerken van de DOM en timers.

useEffectaanvaardt twee argumenten. Het tweede argument is optioneel.

useEffect(<function>, <dependency>)


Laten we als voorbeeld een timer gebruiken.

Voorbeeld:

Gebruik setTimeout()om 1 seconde te tellen na de eerste weergave:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Maar wacht!! Ik blijf tellen, ook al zou het maar één keer moeten tellen!

useEffectdraait op elke render. Dat betekent dat wanneer de telling verandert, er een render plaatsvindt, die vervolgens een ander effect activeert.

Dit is niet wat we willen. Er zijn verschillende manieren om te controleren wanneer bijwerkingen optreden.

We moeten altijd de tweede parameter opnemen die een array accepteert. We kunnen optioneel afhankelijkheden doorgeven aan useEffectin deze array.

1. Geen afhankelijkheid doorgegeven:

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

2. Een lege array:

useEffect(() => {
  //Runs only on the first render
}, []);

3. Props of staatswaarden:

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

Dus, om dit probleem op te lossen, laten we dit effect alleen uitvoeren op de eerste render.

Voorbeeld:

Voer het effect alleen uit op de eerste render:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- add empty brackets here

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Voorbeeld:

Hier is een voorbeeld van een useEffectHook die afhankelijk is van een variabele. Als de countvariabele wordt bijgewerkt, wordt het effect opnieuw uitgevoerd:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

ReactDOM.render(<Counter />, document.getElementById('root'));

Als er meerdere afhankelijkheden zijn, moeten deze worden opgenomen in de useEffectafhankelijkheidsmatrix.


w3schools CERTIFIED . 2022

Gecertificeerd!

Voltooi de React-modules, doe de oefeningen, doe het examen en word w3schools gecertificeerd!!

$95 INSCHRIJVEN

Effect opschonen

Sommige effecten moeten worden opgeschoond om geheugenlekken te verminderen.

Time-outs, abonnementen, gebeurtenislisteners en andere effecten die niet langer nodig zijn, moeten worden verwijderd.

Dit doen we door een return-functie op te nemen aan het einde van de useEffectHook.

Voorbeeld:

Ruim de timer aan het einde van de useEffecthaak op:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let timer = setTimeout(() => {
    setCount((count) => count + 1);
  }, 1000);

  return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById("root"));

Opmerking: om de timer te wissen, moesten we deze een naam geven.


Test jezelf met oefeningen

Oefening:

Wat moet je toevoegen aan het tweede argument van een useEffectHook om het te beperken tot alleen draaien op de eerste render?

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    setData(getData())
  }, );

  return <DisplayData data={data} />;
}

ReactDOM.render(<App />, document.getElementById('root'));