在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
相关产品推荐
相关产品推荐

