NextJS 13 服务端组件独立加载Loading组件实现问询
实现NextJS服务端组件独立加载并显示Loading
要在保持PriceFetch为服务端组件的前提下,实现每个组件独立加载、未完成时显示Loading,核心是利用React Suspense配合NextJS的流式渲染(Streaming),无需客户端状态。
步骤1:创建Loading组件
// app/components/Loading.tsx export default function Loading() { return <div>加载中...</div>; }
步骤2:实现服务端PriceFetch组件
组件内部直接用async/await处理带延迟的数据请求,无需客户端状态:
// app/components/PriceFetch.tsx type Props = { sleepTime: number; }; // 模拟延迟请求函数 async function fetchPrice(sleepTime: number): Promise<{ price: number }> { await new Promise(resolve => setTimeout(resolve, sleepTime)); return { price: Math.random() * 100 }; } export default async function PriceFetch({ sleepTime }: Props) { const priceData = await fetchPrice(sleepTime); return <div>当前价格:{priceData.price.toFixed(2)}</div>; }
步骤3:父组件中用Suspense包裹每个PriceFetch
在父页面(或父组件)中,给每个PriceFetch单独套上Suspense,指定对应的Loading fallback:
// app/page.tsx import { Suspense } from 'react'; import PriceFetch from './components/PriceFetch'; import Loading from './components/Loading'; export default function WatchlistPage() { return ( <div className="watchlist"> <Suspense fallback={<Loading />}> <PriceFetch sleepTime={100} /> </Suspense> <Suspense fallback={<Loading />}> <PriceFetch sleepTime={1000} /> </Suspense> <Suspense fallback={<Loading />}> <PriceFetch sleepTime={10000} /> </Suspense> </div> ); }
原理说明
- 每个
PriceFetch是异步服务端组件,当内部await数据请求时,React会触发对应Suspense的fallback显示Loading。 - NextJS的流式渲染会将页面拆分为多个渲染块,每个
Suspense包裹的组件加载完成后,就会立即流式发送到客户端展示,因此第一个100ms的组件会先显示价格,另外两个继续显示Loading直到各自请求完成。 - 全程无需使用
useState/useEffect等客户端钩子,完全保持服务端组件特性。
内容的提问来源于stack exchange,提问作者3ank
相关产品推荐
相关产品推荐

