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

在Next.js中使用getStaticProps获取API数据时如何展示加载屏

Next.js中getStaticProps加载状态实现方案

首先明确核心逻辑:getStaticProps是服务端/构建阶段执行的方法,它运行在用户访问页面之前,默认情况下用户端不会感知到这个数据获取过程,所以不存在直接在getStaticProps执行期间给用户展示加载态的可能。如果需要展示加载界面,要分三种场景处理:


场景1:增量静态再生(ISR)场景下的加载态

如果你的getStaticProps配置了revalidate参数开启ISR,当触发页面重新生成时,用户首次访问会先拿到旧的静态页面,此时可以结合状态标识区分新旧数据,展示加载态:

// 页面组件
export default function Page({ data }) {
  const [isRevalidating, setIsRevalidating] = useState(false)
  // 可以结合next/router的事件监听重验证过程,切换加载状态
  useEffect(() => {
    const handleStart = (url) => url === router.asPath && setIsRevalidating(true)
    const handleComplete = () => setIsRevalidating(false)
    router.events.on('routerChangeStart', handleStart)
    router.events.on('routerChangeComplete', handleComplete)
    return () => {
      router.events.off('routerChangeStart', handleStart)
      router.events.off('routerChangeComplete', handleComplete)
    }
  }, [router])

  if (isRevalidating) {
    return <div>加载中...</div>
  }
  return <div>实际页面内容 {data}</div>
}

export async function getStaticProps() {
  const data = await fetch(API_END_POINT);
  return {
    props: {
      data
    },
    revalidate: 10 // 示例:10秒重新生成一次页面
  }
}

场景2:动态路由fallback场景的加载态

如果你用的是动态路由+getStaticPaths,设置fallback: true的情况下,首次访问未预生成的页面时,Next.js会先返回fallback页面,此时你可以通过router.isFallback展示加载界面:

import { useRouter } from 'next/router'

export default function Page({ data }) {
  const router = useRouter()
  // fallback状态下展示加载界面
  if (router.isFallback) {
    return <div>加载中...</div>
  }
  return <div>实际页面内容 {data}</div>
}

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }], // 预生成的路径
    fallback: true // 未预生成的路径请求时动态生成
  }
}

export async function getStaticProps({ params }) {
  const data = await fetch(`${API_END_POINT}/${params.id}`);
  return {
    props: {
      data
    }
  }
}

场景3:全量客户端加载的兜底方案

如果你需要每次用户访问页面都触发数据请求并展示加载态,建议把数据获取逻辑移到客户端,配合useEffect实现,getStaticProps仅用来返回初始的占位数据:

import { useEffect, useState } from 'react'

export default function Page({ initialData }) {
  const [data, setData] = useState(initialData)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true)
      const res = await fetch(API_END_POINT)
      const newData = await res.json()
      setData(newData)
      setLoading(false)
    }
    fetchData()
  }, [])

  if (loading) {
    return <div>加载中...</div>
  }
  return <div>实际页面内容 {data}</div>
}

export async function getStaticProps() {
  // 这里可以返回初始占位数据,也可以留空
  return {
    props: {
      initialData: {}
    }
  }
}

内容的提问来源于stack exchange,提问作者Md. Yeasin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:06:05