无需使用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
相关产品推荐
相关产品推荐

