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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:36:03