Ленивая загрузка
lazy позволяет отложить загрузку кода компонента до его первого рендеринга.
const SomeComponent = lazy(load)
Справочник
lazy(load)
Вызовите lazy вне ваших компонентов, чтобы объявить лениво загружаемый React-компонент:
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js')); Параметры
-
load: функция, которая возвращает Promise или другой thenable (объект, похожий на Promise, с методомthen). React не вызоветloadдо первого рендеринга возвращаемого компонента. После первого вызоваloadReact дождётся его разрешения и затем отобразит.defaultвозвращаемого значения как React-компонент. Возвращаемый Promise и значение, разрешающее Promise, будут кэшированы, поэтому React не вызоветloadболее одного раза. Если Promise отклонится, React передаст причину отклонения ближайшему Error Boundary для обработки.
Возвращаемое значение
lazy возвращает React-компонент, который можно отобразить в дереве. Пока код ленивого компонента загружается, попытка его рендеринга приведет к приостановке. Используйте <Suspense>, чтобы отобразить индикатор загрузки во время загрузки.
load функция
Параметры
load не принимает параметров.
Возвращаемое значение
Вам необходимо вернуть Promise или другой thenable (объект, похожий на Promise, с методом then). Он должен в конечном итоге разрешиться в объект, чья .default свойство является допустимым типом React-компонента, таким как функция, memo или forwardRef компонент.
Использование
Ленивая загрузка компонентов с помощью Suspense
Обычно вы импортируете компоненты с помощью статического import объявления:
import MarkdownPreview from './MarkdownPreview.js'; Чтобы отложить загрузку кода этого компонента до его первого рендеринга, замените этот импорт на:
import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js')); Этот код использует динамический import(), что может потребовать поддержки от вашего бандлера или фреймворка. Использование этого шаблона требует, чтобы импортируемый ленивый компонент был экспортирован как default экспорт.
Теперь, когда код вашего компонента загружается по требованию, вам также нужно указать, что должно отображаться во время загрузки. Вы можете сделать это, обернув ленивый компонент или любой из его родителей в <Suspense> блок:
<Suspense fallback={<Loading />}>
<h2>Preview</h2>
<MarkdownPreview />
</Suspense> В этом примере код для MarkdownPreview не будет загружен до тех пор, пока вы не попытаетесь его отобразить. Если MarkdownPreview ещё не загрузился, Loading будет показан вместо него. Попробуйте установить флажок:
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)} /> Show preview </label> <hr /> {showPreview && ( <Suspense fallback={<Loading />}> <h2>Preview</h2> <MarkdownPreview markdown={markdown} /> </Suspense> )} </> ); } // Add a fixed delay so you can see the loading state function delayForDemo(promise) { return new Promise(resolve => { setTimeout(resolve, 2000); }).then(() => promise); }
Этот демонстрационный пример загружается с искусственной задержкой. В следующий раз, когда вы снимете и поставите флажок, Preview будет кэширован, поэтому состояния загрузки не будет. Чтобы увидеть состояние загрузки снова, нажмите «Сбросить» в песочнице.
Узнайте больше о управлении состояниями загрузки с помощью Suspense.
Устранение неполадок
Состояние моего lazy компонента неожиданно сбрасывается
Не объявляйте lazy компоненты *внутри* других компонентов:
import { lazy } from 'react';
function Editor() {
// 🔴 Bad: This will cause all state to be reset on re-renders
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
} Вместо этого всегда объявляйте их на верхнем уровне вашего модуля:
import { lazy } from 'react';
// ✅ Good: Declare lazy components outside of your components
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
function Editor() {
// ...
}
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/reference/react/lazy