Contactez-nous

`Suspense` : Gérer l'état de chargement des composants lazy

Apprenez à utiliser le composant React.Suspense pour afficher un indicateur de chargement (fallback) pendant le chargement des composants avec React.lazy.

Le partenaire indispensable de `React.lazy`

Comme nous l'avons vu, React.lazy permet de différer le chargement du code d'un composant jusqu'à ce qu'il soit nécessaire. Mais que se passe-t-il pendant le court laps de temps où React a décidé de rendre ce composant lazy, mais où le code correspondant n'a pas encore été téléchargé et exécuté par le navigateur ? L'application ne peut pas simplement afficher un vide ou planter.

React a besoin d'un mécanisme pour gérer cet état intermédiaire de "suspension" du rendu, en attendant que le code soit prêt. C'est précisément le rôle du composant React.Suspense.

Suspense vous permet de définir une interface utilisateur de repli (un "fallback") à afficher pendant qu'un ou plusieurs composants enfants chargés paresseusement (via React.lazy) sont en cours de chargement. Il agit comme une "barrière" qui intercepte l'état de suspension déclenché par un composant lazy et affiche le fallback à la place, jusqu'à ce que le composant lazy soit prêt à être rendu.

Utilisation de `Suspense` et de la prop `fallback`

L'utilisation de Suspense est simple : vous l'enveloppez autour du composant (ou de la partie de l'arbre de composants) qui pourrait rendre un composant chargé avec React.lazy. Il prend une prop obligatoire : fallback.

La prop fallback accepte n'importe quel élément React valide (du JSX) qui sera affiché pendant la période de suspension. Cela peut être un simple message texte, un composant spinner, une animation, ou même une structure de page "squelette" (skeleton screen) pour une meilleure expérience visuelle.

import React, { Suspense, lazy } from 'react';

// Composants chargés paresseusement
const AutreComposant = lazy(() => import('./AutreComposant'));
const WidgetLourd = lazy(() => import('./WidgetLourd'));

// Composant de fallback simple
function SpinnerChargement() {
  return 
Chargement...
; } function MonInterface() { const [afficherWidget, setAfficherWidget] = useState(false); return (

Mon Application

{/* Suspense englobe la partie susceptible de charger paresseusement */} }> {/* Section toujours affichée, mais pourrait contenir AutreComposant */}

Section Principale

{/* Section conditionnelle avec un composant lazy */} {afficherWidget && ( )}
); } export default MonInterface;

Dans cet exemple :

  • Si `AutreComposant` ou `WidgetLourd` (lorsqu'il est affiché) déclenche une suspension (parce que leur code n'est pas encore chargé), le composant `Suspense` le plus proche intercepte cet état.
  • Le contenu normal à l'intérieur de `Suspense` (la `section`, le bouton) est temporairement remplacé par le rendu du `fallback` (``).
  • Une fois que tous les composants lazy suspendus sous ce `Suspense` ont chargé leur code, `Suspense` cesse d'afficher le `fallback` et affiche le contenu réel (`section` et `WidgetLourd` si `afficherWidget` est vrai).

Placement et granularité de `Suspense`

Vous pouvez placer des composants `Suspense` à différents endroits de votre arbre de composants pour contrôler la granularité de l'expérience de chargement :

  • Un seul `Suspense` global : Placé haut dans l'application (par exemple, autour de vos `Routes`), il affichera un seul indicateur de chargement global pour n'importe quelle transition de page ou chargement lazy. C'est simple mais peut donner l'impression que toute l'application recharge.
  • Plusieurs `Suspense` : Vous pouvez utiliser plusieurs `Suspense` à différents niveaux. Par exemple, un autour des routes pour le chargement de page, et un autre autour d'un widget spécifique dans une page. Cela permet d'afficher des indicateurs de chargement plus localisés et de ne remplacer que la partie de l'UI qui est effectivement en cours de chargement.
function AppLayout() {
  return (
    
}>
{/* Routes avec composants lazy */}
); } function PageDashboard() { const WidgetStats = lazy(() => import('./WidgetStats')); return (

Dashboard

}>
); }

Dans cet exemple, si l'on navigue vers `/dashboard`, `ChargementPage` s'affiche d'abord. Puis, une fois `PageDashboard` chargé, si `WidgetStats` n'est pas encore prêt, `ChargementWidget` s'affichera à sa place, tandis que le reste de `PageDashboard` (`

`, `GraphiquePrincipal`) sera déjà visible.

Suspense au-delà de `React.lazy`

Il est important de noter que si le cas d'usage principal et stable de `Suspense` est actuellement la gestion du chargement pour `React.lazy`, la vision de l'équipe React pour `Suspense` est plus large. Il est conçu comme un mécanisme générique pour gérer n'importe quelle source de données asynchrone qui peut "suspendre" le rendu pendant qu'elle charge.

Des frameworks comme Relay ou Next.js (avec les React Server Components) et certaines bibliothèques expérimentales de data fetching commencent à intégrer `Suspense` pour gérer également les états de chargement des données API. Cela permet une approche plus unifiée pour afficher les états de chargement, que ce soit pour le code ou pour les données. Cependant, l'utilisation de `Suspense` pour le data fetching n'est pas encore une fonctionnalité stable de React lui-même et dépend souvent de l'intégration avec des frameworks ou des bibliothèques spécifiques.

Pour l'instant, retenez que Suspense est le compagnon indispensable de React.lazy, fournissant le mécanisme élégant pour afficher une UI de repli pendant le chargement du code des composants, améliorant ainsi l'expérience utilisateur lors du code splitting.