lazy
permite que você adie o carregamento do código do componente até que ele seja renderizado pela primeira vez.
const SomeComponent = lazy(load)
Referência
lazy(load)
Chame lazy
fora dos seus componentes para declarar um componente React carregado de forma preguiçosa:
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
Parâmetros
load
: Uma função que retorna uma Promise ou outro thenable (um objeto semelhante a uma Promise com um métodothen
). O React não chamaráload
até a primeira vez que você tentar renderizar o componente retornado. Depois que o React chamaload
pela primeira vez, ele aguardará a resolução e, em seguida, renderizará o valor resolvido como um componente React. Tanto a Promise retornada quanto o valor resolvido da Promise serão armazenados em cache, de modo que o React não chamaráload
mais de uma vez. Se a Promise for rejeitada, o React iráthrow
a razão da rejeição para o mais próximo Error Boundary manipular.
Retornos
lazy
retorna um componente React que você pode renderizar em sua árvore. Enquanto o código do componente preguiçoso ainda estiver carregando, tentar renderizá-lo irá suspender. Use <Suspense>
para exibir um indicador de carregamento enquanto ele está carregando.
Função load
Parâmetros
load
não recebe parâmetros.
Retornos
Você precisa retornar uma Promise ou algum outro thenable (um objeto semelhante a uma Promise com um método then
). Ele precisa eventualmente resolver para um objeto cuja propriedade .default
é um tipo de componente React válido, como uma função, memo
, ou um componente forwardRef
.
Uso
Carregamento preguiçoso de componentes com Suspense
Geralmente, você importa componentes com a declaração estática import
:
import MarkdownPreview from './MarkdownPreview.js';
Para adiar o carregamento do código desse componente até que ele seja renderizado pela primeira vez, substitua essa importação por:
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
Este código depende do import() dinâmico, que pode exigir suporte do seu bundler ou framework. Usar este padrão exige que o componente preguiçoso que você está importando tenha sido exportado como a exportação default
.
Agora que o código do seu componente é carregado sob demanda, você também precisa especificar o que deve ser exibido enquanto ele está carregando. Você pode fazer isso encapsulando o componente preguiçoso ou qualquer um de seus pais em um limite <Suspense>
:
<Suspense fallback={<Loading />}>
<h2>Preview</h2>
<MarkdownPreview />
</Suspense>
Neste exemplo, o código para MarkdownPreview
não será carregado até que você tente renderizá-lo. Se MarkdownPreview
ainda não tiver carregado, Loading
será exibido em seu lugar. Tente marcar a caixa de seleção:
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('Hello, **world**!'); return ( <> <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} /> <label> <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} /> Mostrar prévia </label> <hr /> {showPreview && ( <Suspense fallback={<Loading />}> <h2>Prévia</h2> <MarkdownPreview markdown={markdown} /> </Suspense> )} </> ); } // Adicione um atraso fixo para que você possa ver o estado de carregamento function delayForDemo(promise) { return new Promise(resolve => { setTimeout(resolve, 2000); }).then(() => promise); }
Esta demonstração carrega com um atraso artificial. Da próxima vez que você desmarcar e marcar a caixa de seleção, Prévia
será armazenado em cache, então não haverá estado de carregamento. Para ver o estado de carregamento novamente, clique em “Redefinir” no sandbox.
Saiba mais sobre como gerenciar estados de carregamento com Suspense.
Solução de Problemas
O estado do meu componente lazy
é redefinido inesperadamente
Não declare componentes lazy
dentro de outros componentes:
import { lazy } from 'react';
function Editor() {
// 🔴 Ruim: Isso fará com que todo o estado seja redefinido em novas renderizações
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
}
Em vez disso, sempre declare-os no nível superior do seu módulo:
import { lazy } from 'react';
// ✅ Bom: Declare componentes preguiçosos fora dos seus componentes
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
function Editor() {
// ...
}