lazy
vous permet de différer le chargement du code d’un composant jusqu’à son premier affichage effectif.
const SomeComponent = lazy(load)
Référence
lazy(load)
Appelez lazy
en-dehors de vos composants pour déclarer un composant React chargé à la demande :
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
Voir d’autres exemples ci-dessous.
Paramètres
load
: une fonction qui renvoie une promesse ou un thenable (un objet doté d’une méthodethen
compatible). React n’appellera pasload
tant que vous ne tenterez pas d’afficher le composant renvoyé. Après que React a appeléload
pour la première fois, il patientera pour que la promesse s’établisse, puis affichera la propriété,.default
de la valeur accomplie comme composant React. Tant la promesse renvoyée que sa valeur accomplie seront mises en cache, et React ne rappellera pasload
. Si la promesse rejette, React lèvera (throw
) la raison du rejet (généralement uneError
) pour que le périmètre d’erreur le plus proche la gère.
Valeur renvoyée
lazy
renvoie un composant React que vous pouvez afficher dans votre arborescence. Pendant que le code du composant chargé à la demande se charge, toute tentative de l’afficher suspend. Utilisez <Suspense>
pour afficher un indicateur de chargement pendant ce temps-là.
La fonction load
Paramètres
load
ne prend aucun paramètre.
Valeur renvoyée
Vous aurez besoin de renvoyer une promesse ou un thenable (un objet doté d’une méthode then
compatible). La valeur accomplie doit finalement posséder une propriété .default
qui se comporte comme un composant React valide, tel une qu’une fonction, un composant memo
, ou un composant forwardRef
.
Utilisation
Charger des composants à la demande avec Suspense
En général, vous importez vos composants avec la déclaration statique import
:
import MarkdownPreview from './MarkdownPreview.js';
Pour différer le chargement du code de ce composant jusqu’à ce qu’il affiche pour la première fois, remplacez cette importation avec :
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
Ce code s’appuie sur l’importation dynamique import()
,, ce qui peut nécessiter une prise en charge de votre bundler ou framework. Pour utiliser cette approche, le composant chargé à la demande que vous importez doit être exporté sous le nom default
(ce qui est notamment le cas de l’export par défaut).
Maintenant que le code de votre composant se charge à la demande, vous aurez besoin de spécifier ce qui devrait être affiché pendant son chargement. Vous pouvez le faire en enrobant le composant chargé à la demande ou l’un de ses parents dans un périmètre <Suspense>
:
<Suspense fallback={<Loading />}>
<h2>Aperçu</h2>
<MarkdownPreview />
</Suspense>
Dans cet exemple, le code de MarkdownPreview
ne sera pas chargé jusqu’à ce que vous essayiez de l’afficher. Si MarkdownPreview
n’est pas encore chargé, Loading
sera affiché à sa place. Essayez de cocher la case :
import { useState, Suspense, lazy } from 'react'; import Loading from './Loading.js'; const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js'))); export default function MarkdownEditor() { const [showPreview, setShowPreview] = useState(false); const [markdown, setMarkdown] = useState('Salut **tout le monde** !'); return ( <> <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} /> <label> <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} /> Afficher l’aperçu </label> <hr /> {showPreview && ( <Suspense fallback={<Loading />}> <h2>Aperçu</h2> <MarkdownPreview markdown={markdown} /> </Suspense> )} </> ); } // Ajouter un délai fixe pour voir l’état de chargement function delayForDemo(promise) { return new Promise(resolve => { setTimeout(resolve, 2000); }).then(() => promise); }
Cette démo se charge avec un retard artificiel. La prochaine fois que vous décochez et cochez la case, Preview
sera mis en cache, il n’y aura donc pas d’état de chargement. Pour voir à nouveau l’état de chargement, cliquez sur « Réinitialiser » dans le bac à sable.
En savoir plus sur la gestion des états de chargement avec Suspense.
Dépannage
L’état de mon composant lazy
est réinitialisé de façon inattendue
Ne déclarez pas les composants lazy
à l’intérieur d’autres composants :
import { lazy } from 'react';
function Editor() {
// 🔴 Erroné : ça entraînera la réinitialisation de tous les états lors des réaffichages
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
}
Déclarez-les toujours plutôt au début de votre module :
import { lazy } from 'react';
// ✅ Correct : déclarez les composants lazy en-dehors de vos composants
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
function Editor() {
// ...
}