You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需使用React.lazy实现Suspense:原理及示例解析

React Suspense 不依赖React.lazy的实现原理与示例

核心原理

Suspense的核心逻辑是捕获子组件渲染时抛出的Promise:

  • 当组件在渲染过程中抛出Promise,Suspense会暂停该组件的渲染流程,立即展示你设置的fallback回退内容。
  • 待Promise状态变为resolved后,Suspense会重新触发该组件的渲染,此时组件就能拿到异步结果并正常渲染。

React.lazy只是封装了动态导入模块时生成的Promise,本质也是利用上述机制,所以我们完全可以手动实现抛出Promise的逻辑,不需要依赖lazy。

自定义异步组件示例

下面是一个模拟2秒后加载完成的异步组件,结合Suspense实现回退渲染:

import { Suspense } from 'react';

// 模拟异步数据获取:2秒后返回结果
function fetchAsyncContent() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("2秒加载完成!这是异步渲染的主内容");
    }, 2000);
  });
}

// 自定义异步组件
let cachedContent = null;
let loadingPromise = null;

function AsyncComponent() {
  // 若未缓存内容,触发异步加载并抛出Promise
  if (!cachedContent) {
    // 仅创建一次Promise,避免重复请求
    if (!loadingPromise) {
      loadingPromise = fetchAsyncContent().then(content => {
        cachedContent = content;
      });
    }
    throw loadingPromise;
  }

  // 内容加载完成后渲染
  return <div className="content">{cachedContent}</div>;
}

// 父组件中使用Suspense包裹
function App() {
  return (
    <div className="app">
      <h2>Suspense 自定义异步渲染示例</h2>
      <Suspense fallback={<div className="loading">正在加载中...</div>}>
        <AsyncComponent />
      </Suspense>
    </div>
  );
}

export default App;

示例说明

  • 首次渲染AsyncComponent时,cachedContent为null,组件会创建Promise并抛出,Suspense捕获后展示“正在加载中...”。
  • 2秒后Promise resolve,cachedContent被赋值为异步结果,Suspense重新渲染AsyncComponent,此时显示最终内容。
  • 将cachedContent和loadingPromise放在组件外部,是为了避免组件每次重新渲染都重复发起异步请求,保证请求只执行一次。

内容的提问来源于stack exchange,提问作者Dhruv Property

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:07:10