Contactez-nous

`useEffect` avec dépendances vides (`[]`) (montage uniquement)

Maîtrisez l'utilisation de useEffect avec un tableau de dépendances vide ([]) pour exécuter des effets uniquement lors du montage du composant React.

Comprendre l'exécution unique au montage avec `useEffect`

Le hook `useEffect` est un outil puissant pour gérer les effets de bord dans les composants fonctionnels React. Une configuration particulière, mais très fréquente, consiste à fournir un tableau de dépendances vide (`[]`) comme second argument. Cette configuration dicte à React un comportement bien précis : l'effet ne doit s'exécuter qu'une seule fois, juste après le premier rendu du composant (le montage).

Pourquoi ce comportement ? Lorsque vous fournissez un tableau de dépendances, React compare les valeurs de ces dépendances entre les rendus successifs. Si aucune des valeurs n'a changé, React saute l'exécution de l'effet pour optimiser les performances. Avec un tableau vide, il n'y a aucune dépendance à surveiller. Par conséquent, après l'exécution initiale lors du montage, React considérera toujours que les dépendances n'ont pas changé (puisqu'il n'y en a pas) et ne réexécutera jamais l'effet lors des mises à jour suivantes du composant.

Il est crucial de distinguer ce comportement de celui d'un `useEffect` sans second argument (le tableau de dépendances est omis). Dans ce dernier cas, l'effet s'exécute après *chaque* rendu, ce qui est souvent indésirable et peut entraîner des problèmes de performance ou des boucles infinies. L'utilisation de `[]` est donc la méthode standard pour simuler le comportement de `componentDidMount` des anciens composants classe.

Cette approche est idéale pour toutes les opérations d'initialisation qui ne doivent se produire qu'une seule fois pendant la durée de vie du composant, indépendamment des changements de props ou d'état ultérieurs. Pensez-y comme à la mise en place initiale de votre composant une fois qu'il est ajouté au DOM.

Cas d'usage typiques de `useEffect` avec dépendances vides

L'un des cas d'utilisation les plus courants pour `useEffect(..., [])` est le chargement initial de données depuis une API. Vous voulez typiquement récupérer ces données une seule fois lorsque le composant apparaît à l'écran, sans relancer la requête à chaque mise à jour.

import React, { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    console.log('Fetching user data only on mount for userId:', userId);
    setLoading(true);
    fetch(`/api/users/${userId}`)
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then(data => {
        setUser(data);
        setLoading(false);
      })
      .catch(err => {
        console.error("Failed to fetch user:", err);
        setError(err.message);
        setLoading(false);
      });

    // Note: Dans un cas réel, si userId peut changer, il faudrait l'inclure
    // dans les dépendances. Ici, on suppose qu'il est fixe pour ce composant
    // ou que le composant est remonté si userId change.
    // Si userId *doit* être une dépendance, ce n'est plus un montage unique.
    // Cet exemple illustre le pattern, mais attention aux dépendances implicites.

  }, []); // <-- Tableau de dépendances vide

  if (loading) return 
Chargement...
; if (error) return
Erreur: {error}
; if (!user) return null; return (

{user.name}

Email: {user.email}

); } export default UserProfile;

Un autre usage fréquent est la mise en place d'abonnements (subscriptions) ou d'écouteurs d'événements globaux (sur `window` ou `document`). Ces éléments doivent souvent être établis une seule fois au montage et nettoyés au démontage. Par exemple, écouter les changements de taille de la fenêtre ou s'abonner à un service de messagerie en temps réel.

On peut également l'utiliser pour interagir directement avec le DOM (bien que ce soit à utiliser avec parcimonie) pour des initialisations spécifiques, comme l'intégration d'une bibliothèque JavaScript tierce non-React qui a besoin de s'accrocher à un élément du DOM une fois celui-ci rendu.

Il est essentiel de s'assurer qu'aucune variable ou fonction définie à l'intérieur du composant (props, state, ou fonctions locales) n'est utilisée dans l'effet sans être listée dans les dépendances. Si une telle variable est utilisée et que le tableau reste vide (`[]`), l'effet utilisera la valeur initiale de cette variable (issue de la closure du premier rendu) et ne réagira pas à ses mises à jour, ce qui peut introduire des bugs subtils. L'outil de linting ESLint pour les hooks (`eslint-plugin-react-hooks`) est très utile pour détecter ces oublis.

Nettoyage au démontage : La fonction de retour

Lorsque vous utilisez `useEffect` avec un tableau de dépendances vide, la fonction de nettoyage que vous pouvez retourner depuis l'effet acquiert également un comportement spécifique. Elle ne sera exécutée qu'une seule et unique fois : lorsque le composant est sur le point d'être retiré du DOM (démontage ou unmount).

Ceci est le pendant direct de la méthode `componentWillUnmount` des composants classe. C'est l'endroit idéal pour annuler les opérations mises en place lors du montage : annuler les requêtes réseau en cours, se désabonner des services, retirer les écouteurs d'événements ajoutés manuellement, ou libérer toute autre ressource.

Voici un exemple illustrant la mise en place et le nettoyage d'un écouteur d'événement :

import React, { useState, useEffect } from 'react';

function WindowWidthLogger() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    // Fonction pour mettre à jour la largeur
    const handleResize = () => {
      console.log('Window resized, updating width...');
      setWidth(window.innerWidth);
    };

    // Ajout de l'écouteur au montage
    window.addEventListener('resize', handleResize);
    console.log('Event listener added on mount.');

    // Fonction de nettoyage
    return () => {
      window.removeEventListener('resize', handleResize);
      console.log('Event listener removed on unmount.');
    };
  }, []); // <-- Exécution unique au montage et nettoyage au démontage

  return (
    
Largeur de la fenêtre : {width}px
); } export default WindowWidthLogger;

Omettre la fonction de nettoyage pour des opérations comme l'ajout d'écouteurs ou la création d'abonnements est une source fréquente de fuites mémoire dans les applications React. Le composant est retiré du DOM, mais l'écouteur ou l'abonnement persiste, potentiellement en conservant une référence au composant et en empêchant sa destruction par le garbage collector, ou en continuant à réagir à des événements inutilement.

En résumé, `useEffect(effectFn, [])` exécute `effectFn` une fois après le montage initial. Si `effectFn` retourne une fonction `cleanupFn`, alors `cleanupFn` sera exécutée une seule fois, juste avant le démontage du composant. C'est un pattern fondamental pour gérer le cycle de vie d'initialisation et de nettoyage dans les composants fonctionnels React.