Reaguj useEffect
haki
useEffect
Hook pozwala na wykonywanie efektów ubocznych w twoich komponentach .
Niektóre przykłady efektów ubocznych to: pobieranie danych, bezpośrednia aktualizacja DOM i liczniki czasu.
useEffect
przyjmuje dwa argumenty. Drugi argument jest opcjonalny.
useEffect(<function>, <dependency>)
Jako przykładu użyjmy timera.
Przykład:
Służy setTimeout()
do odliczania 1 sekundy po wstępnym renderowaniu:
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'));
Ale poczekaj!! Ciągle liczę, chociaż powinno liczyć tylko raz!
useEffect
działa na każdym renderze. Oznacza to, że gdy zmienia się liczba, następuje renderowanie, które następnie wyzwala inny efekt.
Nie tego chcemy. Istnieje kilka sposobów kontrolowania wystąpienia efektów ubocznych.
Powinniśmy zawsze uwzględniać drugi parametr, który akceptuje tablicę. Opcjonalnie możemy przekazać zależności useEffect
w tej tablicy.
1. Nie przeszła żadna zależność:
useEffect(() => {
//Runs on every render
});
2. Pusta tablica:
useEffect(() => {
//Runs only on the first render
}, []);
3. Rekwizyty lub wartości stanów:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
Aby rozwiązać ten problem, uruchommy ten efekt tylko przy początkowym renderowaniu.
Przykład:
Uruchom efekt tylko na początkowym renderowaniu:
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'));
Przykład:
Oto przykład useEffect
hooka, który jest zależny od zmiennej. Jeśli count
zmienna się zaktualizuje, efekt uruchomi się ponownie:
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'));
Jeśli istnieje wiele zależności, należy je uwzględnić w useEffect
tablicy zależności.
Zostać certyfikowanym!
95 $ ZAPISZ
Czyszczenie efektów
Niektóre efekty wymagają oczyszczenia w celu zmniejszenia wycieków pamięci.
Limity czasu, subskrypcje, detektory zdarzeń i inne efekty, które nie są już potrzebne, należy usunąć.
Robimy to, dołączając funkcję powrotu na końcu useEffect
hooka.
Przykład:
Wyczyść licznik czasu na końcu useEffect
haka:
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"));
Uwaga: Aby wyczyścić timer, musieliśmy go nazwać.