lazy 允许你推迟加载组件的代码,直到它第一次渲染。

¥lazy lets you defer loading component’s code until it is rendered for the first time.

const SomeComponent = lazy(load)

参考

¥Reference

lazy(load)

在组件外部调用 lazy 以声明延迟加载的 React 组件:

¥Call lazy outside your components to declare a lazy-loaded React component:

import { lazy } from 'react';

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

请参阅下面的更多示例。

¥See more examples below.

参数

¥Parameters

  • load:一个函数,返回 Promise 或另一个 thenable(具有 then 方法的类似 Promise 的对象)。在你第一次尝试渲染返回的组件之前,React 不会调用 load。React 首先调用 load 后,会等待它解析,然后将解析值的 .default 渲染为 React 组件。返回的 Promise 和 Promise 的解析值都会被缓存,所以 React 不会多次调用 load。如果 Promise 拒绝,React 将 throw 拒绝原因到最近的错误边界来处理。

    ¥load: A function that returns a Promise or another thenable (a Promise-like object with a then method). React will not call load until the first time you attempt to render the returned component. After React first calls load, it will wait for it to resolve, and then render the resolved value’s .default as a React component. Both the returned Promise and the Promise’s resolved value will be cached, so React will not call load more than once. If the Promise rejects, React will throw the rejection reason for the nearest Error Boundary to handle.

返回

¥Returns

lazy 返回一个可以在树中渲染的 React 组件。当惰性组件的代码仍在加载时,尝试渲染它将会挂起。使用 <Suspense> 在加载时显示加载指示器。

¥lazy returns a React component you can render in your tree. While the code for the lazy component is still loading, attempting to render it will suspend. Use <Suspense> to display a loading indicator while it’s loading.


load 函数

¥load function

参数

¥Parameters

load 没有参数。

¥load receives no parameters.

返回

¥Returns

你需要返回一个 Promise 或其他一些 thenable(具有 then 方法的类似 Promise 的对象)。它最终需要解析为 .default 属性是有效 React 组件类型的对象,例如函数、memoforwardRef 组件。

¥You need to return a Promise or some other thenable (a Promise-like object with a then method). It needs to eventually resolve to an object whose .default property is a valid React component type, such as a function, memo, or a forwardRef component.


用法

¥Usage

使用 Suspense 延迟加载组件

¥Lazy-loading components with Suspense

通常,你使用静态 import 声明导入组件:

¥Usually, you import components with the static import declaration:

import MarkdownPreview from './MarkdownPreview.js';

要推迟加载此组件的代码,直到它第一次渲染,请将此导入替换为:

¥To defer loading this component’s code until it’s rendered for the first time, replace this import with:

import { lazy } from 'react';

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

此代码依赖于 动态 import(),它可能需要你的打包器或框架的支持。使用此模式要求将你导入的惰性组件导出为 default 导出。

¥This code relies on dynamic import(), which might require support from your bundler or framework. Using this pattern requires that the lazy component you’re importing was exported as the default export.

现在你的组件代码已按需加载,你还需要指定加载时应显示的内容。你可以通过将惰性组件或其任何父级封装到 <Suspense> 边界中来做到这一点:

¥Now that your component’s code loads on demand, you also need to specify what should be displayed while it is loading. You can do this by wrapping the lazy component or any of its parents into a <Suspense> boundary:

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

在此示例中,直到你尝试渲染 MarkdownPreview 的代码时才会加载它。如果 MarkdownPreview 尚未加载,Loading 将显示在其位置。尝试勾选复选框:

¥In this example, the code for MarkdownPreview won’t be loaded until you attempt to render it. If MarkdownPreview hasn’t loaded yet, Loading will be shown in its place. Try ticking the 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('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 将被缓存,因此不会有加载状态。要再次查看加载状态,请单击沙盒上的 “重置”。

¥This demo loads with an artificial delay. The next time you untick and tick the checkbox, Preview will be cached, so there will be no loading state. To see the loading state again, click “Reset” on the sandbox.

了解有关使用 Suspense 管理加载状态的更多信息。

¥Learn more about managing loading states with Suspense.


故障排除

¥Troubleshooting

我的 lazy 组件的状态意外重置

¥My lazy component’s state gets reset unexpectedly

不要在其他组件中声明 lazy 组件:

¥Do not declare lazy components inside other components:

import { lazy } from 'react';

function Editor() {
// 🔴 Bad: This will cause all state to be reset on re-renders
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
}

而是,始终在模块的顶层声明它们:

¥Instead, always declare them at the top level of your module:

import { lazy } from 'react';

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

function Editor() {
// ...
}

React 中文网 - 粤ICP备13048890号