Next.js中getServerSideProps如何实现类似客户端的loading加载状态
Next.js SSR 场景实现加载状态方案
首先明确传统 Pages Router 下直接在组件内判断 !data 不生效的原因:getServerSideProps 默认会在服务端等待所有异步请求完成后,才会将组装好的页面数据和 HTML 返回给客户端,因此组件首次渲染时 props 必然包含完整数据,空值判断永远不会触发。
方案1:结合getServerSideProps返回Promise属性特性 + React Suspense
该特性允许你直接将未 resolve 的 Promise 作为props返回,配合React 18的Suspense和useAPI即可实现加载状态,示例如下:
第一步:修改getServerSideProps返回Promise
export async function getServerSideProps() { // 不要await请求,直接返回Promise本身 const postsPromise = getAllPosts(); return { props: { postsPromise, }, }; }
第二步:组件层用Suspense包裹实现加载态
import { Suspense, use } from 'react'; import { useRouter } from 'next/router'; // 你自己实现的骨架屏组件,也可以用react-loading-skeleton import PostListSkeleton from './PostListSkeleton'; function AllPostsPage({ postsPromise }) { const router = useRouter(); // 用use API解析Promise const posts = use(postsPromise); function findPostsHandler(year, month) { const fullPath = `/posts/${year}/${month}`; router.push(fullPath); } return ( <> <PostsSearch onSearch={findPostsHandler} /> <PostList items={posts} /> </> ); } // 外层用Suspense包裹,fallback属性值就是加载状态下展示的内容 export default function WrappedAllPostsPage(props) { return ( <Suspense fallback={<PostListSkeleton />}> <AllPostsPage {...props} /> </Suspense> ) }
方案2:Next.js 13+ App Router 流式渲染
如果使用App Router,原生支持流式渲染和Suspense,不需要额外配置getServerSideProps,直接在服务端组件内编写数据请求逻辑,将需要加载的模块用Suspense包裹即可,框架会自动先返回骨架屏内容,待数据请求完成后再替换为真实内容。
补充:路由跳转时的加载状态
如果是客户端路由跳转场景的加载需求,你可以监听路由事件控制加载状态的显隐:
- Pages Router:监听
router.events的routeChangeStart、routeChangeComplete、routeChangeError事件 - App Router:用
useNavigation钩子的isPending状态判断跳转状态
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

