Crochets de useEffectréaction


Le useEffectcrochet vous permet d'effectuer des effets secondaires dans vos composants.

Quelques exemples d'effets secondaires sont : la récupération de données, la mise à jour directe du DOM et les minuteries.

useEffectaccepte deux arguments. Le deuxième argument est facultatif.

useEffect(<function>, <dependency>)


Prenons une minuterie comme exemple.

Exemple:

Utilisez setTimeout()pour compter 1 seconde après le rendu initial :

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

Mais attendez!! Je continue de compter même si ça ne devrait compter qu'une fois !

useEffects'exécute sur chaque rendu. Cela signifie que lorsque le nombre change, un rendu se produit, qui déclenche alors un autre effet.

Ce n'est pas ce que nous voulons. Il existe plusieurs façons de contrôler le moment où les effets secondaires se manifestent.

Nous devons toujours inclure le deuxième paramètre qui accepte un tableau. Nous pouvons éventuellement transmettre des dépendances à useEffectdans ce tableau.

1. Aucune dépendance passée :

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

2. Un tableau vide :

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

3. Props ou valeurs d'état :

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

Donc, pour résoudre ce problème, exécutons cet effet uniquement sur le rendu initial.

Exemple:

N'exécutez l'effet que sur le rendu initial :

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

Exemple:

Voici un exemple de useEffectHook dépendant d'une variable. Si la countvariable est mise à jour, l'effet s'exécutera à nouveau :

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

S'il existe plusieurs dépendances, elles doivent être incluses dans le useEffecttableau de dépendances.


w3schools CERTIFIED . 2022

Obtenir une certification!

Complétez les modules React, faites les exercices, passez l'examen et devenez certifié w3schools !!

95 $ S'INSCRIRE

Nettoyage d'effet

Certains effets nécessitent un nettoyage pour réduire les fuites de mémoire.

Les délais d'expiration, les abonnements, les écouteurs d'événements et les autres effets qui ne sont plus nécessaires doivent être supprimés.

Nous faisons cela en incluant une fonction de retour à la fin du useEffectHook.

Exemple:

Nettoyez la minuterie à la fin du useEffectcrochet :

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

Remarque : Pour effacer la minuterie, nous avons dû lui donner un nom.


Testez-vous avec des exercices

Exercer:

Que devez-vous ajouter au deuxième argument d'un useEffectcrochet pour le limiter à s'exécuter uniquement sur le premier rendu ?

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