Haken useEffectreagieren


Mit dem useEffectHook können Sie Nebeneffekte in Ihren Komponenten ausführen.

Einige Beispiele für Nebeneffekte sind: Abrufen von Daten, direktes Aktualisieren des DOM und Timer.

useEffectakzeptiert zwei Argumente. Das zweite Argument ist optional.

useEffect(<function>, <dependency>)


Nehmen wir als Beispiel einen Timer.

Beispiel:

Verwenden Sie setTimeout(), um 1 Sekunde nach dem ersten Rendern zu zählen:

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'));

Aber warte!! Ich zähle weiter, obwohl es nur einmal zählen sollte!

useEffectläuft auf jedem render. Das heißt, wenn sich der Zähler ändert, passiert ein Render, der dann einen anderen Effekt auslöst.

Das wollen wir nicht. Es gibt mehrere Möglichkeiten, um zu kontrollieren, wann Nebenwirkungen auftreten.

Wir sollten immer den zweiten Parameter einschließen, der ein Array akzeptiert. Wir können optional Abhängigkeiten an useEffectdieses Array übergeben.

1. Keine Abhängigkeit bestanden:

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

2. Ein leeres Array:

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

3. Requisiten oder Zustandswerte:

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

Um dieses Problem zu beheben, führen wir diesen Effekt also nur beim ersten Rendern aus.

Beispiel:

Führen Sie den Effekt nur beim anfänglichen Rendern aus:

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'));

Beispiel:

Hier ist ein Beispiel für einen useEffectHook, der von einer Variablen abhängig ist. Wenn die countVariable aktualisiert wird, wird der Effekt erneut ausgeführt:

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'));

Wenn mehrere Abhängigkeiten vorhanden sind, sollten sie in das useEffectAbhängigkeitsarray aufgenommen werden.


w3schools CERTIFIED . 2022

Zertifiziert werden!

Absolvieren Sie die React-Module, machen Sie die Übungen, machen Sie die Prüfung und werden Sie w3schools-zertifiziert!!

$ 95 REGISTRIEREN

Effektbereinigung

Einige Effekte erfordern eine Bereinigung, um Speicherverluste zu reduzieren.

Timeouts, Abonnements, Ereignis-Listener und andere Effekte, die nicht mehr benötigt werden, sollten entsorgt werden.

Dazu fügen wir am Ende des useEffectHooks eine Return-Funktion ein.

Beispiel:

Bereinigen Sie den Timer am Ende des useEffectHooks:

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"));

Hinweis: Um den Timer zu löschen, mussten wir ihm einen Namen geben.


Testen Sie sich mit Übungen

Übung:

Was müssen Sie zum zweiten Argument eines useEffectHooks hinzufügen, um ihn darauf zu beschränken, nur beim ersten Rendern ausgeführt zu werden?

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'));