lazy te permite diferir la carga del código del componente hasta que se renderice por primera vez.

const SomeComponent = lazy(load)

Referencia

lazy(load)

Llama a lazy fuera de tus componentes para declarar un componente de carga diferida:

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

Ver más ejemplos abajo.

Parámetros

  • load: Una función que devuelve una Promise u otro thenable (un objeto tipo Promise con un método then). React no llamará a load hasta la primera vez que intentes renderizar el componente devuelto. Después de que React llame por primera vez a load, esperará a que se resuelva, y entonces renderizará el valor resuelto .default como un componente React. Tanto la Promise devuelta como el valor resuelto de la Promise se almacenarán en caché, por lo que React no llamará a load más de una vez. Si la Promise es rechazada, React lanzará el motivo de rechazo a la barrera de error más cercana.

Devuelve

lazy devuelve un componente React que puedes renderizar en tu árbol. Mientras el código del componente lazy sigue cargando, el intento de renderizarlo se suspenderá. Usa <Suspense> para mostrar un indicador de carga mientras se carga.


Función load

Parámetros

load no recibe parámetros.

Devuelve

Necesitas devolver una Promise o algún otro thenable (un objeto tipo Promise con un método then). Es necesario que eventualmente resuelva a un objeto cuya propiedad .default sea un tipo de componente React válido, como una función, memo, o un componente forwardRef.


Uso

Componentes de carga diferida con Suspense

Por lo general, importas componentes con la declaración estática import:

import MarkdownPreview from './MarkdownPreview.js';

Para diferir la carga del código de este componente hasta que se renderice por primera vez, reemplaza esta importación con:

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

Este código se basa en import() dinámico, que puede requerir el soporte de tu empaquetador o framework. Usar este patrón requiere que el componente lazy que estás importando haya sido exportado como export default.

Ahora que el código de tu componente se carga bajo demanda, también debes especificar qué debe mostrarse mientras se carga. Puedes hacer esto envolviendo el componente lazy o cualquiera de sus padres en una barrera de <Suspense>:

<Suspense fallback={<Loading />}>
<h2>Preview</h2>
<MarkdownPreview />
</Suspense>

En este ejemplo, el código para MarkdownPreview no se cargará hasta que intentes renderizarlo. Si MarkdownPreview aún no se ha cargado, Loading se mostrará en su lugar. Intenta marcar el checkbox:

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('¡Hola, **mundo**!');
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Show preview
      </label>
      <hr />
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Preview</h2>
          <MarkdownPreview markdown={markdown} />
        </Suspense>
      )}
    </>
  );
}

// Agrega un retardo fijo para que puedas ver el estado de carga
function delayForDemo(promise) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}

Esta demostración se carga con un retraso artificial. La próxima vez que desmarques y marques el checkbox, Preview se almacenará en caché, por lo que no se mostrará ningún estado de carga. Para ver nuevamente el estado de carga, haz clic en «Reiniciar» en el sandbox.

Obtén más información sobre cómo administrar los estados de carga con Suspense.


Solución de problemas

Mi estado del componente lazy se reinicia inesperadamente

No declarares componentes lazy dentro de otros componentes:

import { lazy } from 'react';

function Editor() {
// 🔴 Mal: Esto causará que todo el estado se reinicie en los re-renderizados.
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
}

En cambio, decláralos siempre en el nivel superior de tu módulo:

import { lazy } from 'react';

// ✅ Good: Declare lazy components outside of your components
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

function Editor() {
// ...
}