Reagovat useEffectHooks


useEffectHook vám umožňuje provádět vedlejší efekty ve vašich komponentách .

Některé příklady vedlejších účinků jsou: načítání dat, přímá aktualizace DOM a časovače.

useEffectpřijímá dva argumenty. Druhý argument je volitelný.

useEffect(<function>, <dependency>)


Použijme jako příklad časovač.

Příklad:

Použijte setTimeout()k počítání 1 sekundy po počátečním vykreslení:

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 počkej!! Počítám dál, i když by se to mělo počítat jen jednou!

useEffectběží na každém renderu. To znamená, že když se počet změní, dojde k vykreslení, které pak spustí další efekt.

To není to, co chceme. Existuje několik způsobů, jak kontrolovat výskyt vedlejších účinků.

Vždy bychom měli zahrnout druhý parametr, který pole přijímá. useEffectV tomto poli můžeme volitelně předat závislosti .

1. Neprošla žádná závislost:

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

2. Prázdné pole:

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

3. Rekvizity nebo státní hodnoty:

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

Abychom tento problém vyřešili, spusťte tento efekt pouze na počátečním vykreslení.

Příklad:

Spusťte efekt pouze na počátečním vykreslení:

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

Příklad:

Zde je příklad useEffectháku, který je závislý na proměnné. Pokud se countproměnná aktualizuje, efekt se spustí znovu:

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

Pokud existuje více závislostí, měly by být zahrnuty do useEffectpole závislostí.


w3schools CERTIFIED . 2022

Získejte certifikaci!

Dokončete moduly React, proveďte cvičení, udělejte zkoušku a získejte certifikaci w3schools!!

95 $ PŘIHLÁSIT SE

Vyčištění efektu

Některé efekty vyžadují vyčištění, aby se snížilo nevracení paměti.

Časové limity, předplatná, posluchače událostí a další efekty, které již nejsou potřeba, by měly být zlikvidovány.

useEffectToho dosáhneme tak, že na konec háku zařadíme funkci návratu .

Příklad:

Vyčistěte časovač na konci useEffectháku:

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

Poznámka: Abychom vyčistili časovač, museli jsme jej pojmenovat.


Otestujte se pomocí cvičení

Cvičení:

Co musíte přidat k druhému argumentu useEffectháku, abyste jej omezili na spuštění pouze na prvním vykreslení?

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