Comprendre et utiliser le Hook useEffect en React
Le hook useEffect
permet d'exécuter du code à différents moments du cycle de vie d'un composant fonctionnel, notamment lors du montage, de la mise à jour et du démontage du composant.
Définition du hook useEffect
- Le premier paramètre est une fonction de rappel (callback) qui sera exécutée dès lors qu’une dépendance change.
- Le second paramètre est un tableau de dépendances, qui sont des variables.
import { useState, useEffect } from "react";
export default function App() {
const [title, setTitle] = useState("");
useEffect(() => {
console.log("Appelé lorsque le titre change");
}, [title]);
const handleChange = (e) => {
setTitle(e.target.value);
};
return (
<>
<input type="text" name="title" value={title} onChange={handleChange} />
</>
);
}
Utilisation de base de useEffect
Le Hook useEffect
s'exécute par défaut à chaque rendu, c'est-à-dire aussi bien lors du montage initial que lors de chaque mise à jour du composant.
useEffect(() => {
console.log('Exécuter au montage du composant et lors de la mise à jour de son état');
});
Exécuter useEffect uniquement lors du montage
Si vous souhaitez que useEffect
soit exécuté uniquement lors du montage initial du composant (et non lors des mises à jour suivantes), vous pouvez passer un tableau vide []
comme second argument. Ce tableau agit comme une liste de dépendances, et en l’absence de dépendances, l'effet ne sera exécuté qu'une seule fois, au montage.
useEffect(() => {
console.log("Exécuter uniquement au montage du composant");
}, []);
Exécuter useEffect lors de la mise à jour d'une dépendance
Le problème avec React est qu’à chaque changement de l’état du composant, celui-ci sera à nouveau rendu, et donc l’ensemble du code du composant sera complètement réexécuté, ce qui peut entraîner des calculs inutiles.
L’avantage de useEffect
est que le code dans le callback sera exécuté uniquement lorsqu'une des propriétés définies dans le second paramètre change.
Par exemple, si vous ne voulez que l'effet soit déclenché uniquement lors des modifications de la propriété title
, vous pouvez l'ajouter dans ce tableau :
useEffect(() => {
console.log("Exécuter lors du montage du composant et à la mise à jour de la propriété title");
}, [title]);
Nettoyage lors du démontage du composant React
Il est important d'effectuer un nettoyage lors du démontage d'un composant en retournant une fonction depuis le hook useEffect
. Cette fonction de nettoyage est particulièrement utile pour désabonner des événements ou annuler des effets précédemment mis en place, comme des timers.
useEffect(() => {
const handler = (e) => console.log("scrolled");
window.addEventListener("scroll", handler);
return () => window.removeEventListener("scroll", handler);
}, [title]);
Dans le cas des appels API effectués dans useEffect
, l'utilisation de AbortController
permet d'annuler une requête en cours. Cela est particulièrement pertinent lorsque le composant est démonté puis remonté rapidement, évitant ainsi des appels API redondants, dont le premier deviendrait inutile.
useEffect(() => {
const abortController = new AbortController();
const signal = abortController.signal;
const response = await fetch('/todo', { signal });
return () => abortController.abort();
}, []);
Bonne pratique lors de l'utilisation du hook useEffect
Le useEffect
est dédié aux effets de bord et non à la mise à jour d’une propriété lorsqu'une autre change. Si vous appelez un setter à l’intérieur de useEffect
, cela signifie probablement que vous faites quelque chose de mal et qu’il existe une autre manière de procéder.
La raison est que si vous utilisez un setter dans useEffect
, le composant sera rendu deux fois : une première fois lorsque la dépendance de useEffect
est mise à jour, et une seconde fois suite à l’appel du setter dans useEffect
. Il est donc préférable d’éviter cette pratique autant que possible.