Next.js路由重新验证时如何显示加载器?是否存在isRevalidating标识?
在Next.js中ISR重新验证时显示加载器的实现方案
首先明确:Next.js 本身没有直接暴露名为isRevalidating的内置标识,但可以通过不同路由方案(Pages Router/App Router)结合数据缓存库或自定义逻辑实现需求。
一、Pages Router 方案(适配你的getStaticProps场景)
结合SWR库监听数据重新验证状态,以此控制加载器显示:
- 安装SWR
npm install swr
- 页面组件改造
不再直接通过getStaticProps传递数据,改用SWR在客户端请求数据接口,利用其isValidating状态判断是否处于重新验证阶段:
import useSWR from 'swr' // 数据请求工具函数 const fetcher = (...args) => fetch(...args).then(res => res.json()) export default function TargetPage() { const { data, error, isValidating } = useSWR('/api/your-data', fetcher, { revalidateOnFocus: false, revalidateOnReconnect: false, refreshInterval: 60000, // 和ISR的revalidate时间同步(60秒) }) if (error) return <div>加载失败</div> // 初始加载时的状态处理 if (!data && !isValidating) return <div>初始加载中...</div> return ( <div> {/* 重新验证时显示加载器 */} {isValidating && <div className="loader">正在更新内容...</div>} <div>{/* 页面核心内容渲染 */}</div> </div> ) }
- 对应API路由实现
在pages/api/your-data.js中复用原getStaticProps里的数据获取逻辑:
export default async function handler(req, res) { // 复制你原来在getStaticProps中的数据获取代码 const data = await fetchTargetData() res.status(200).json(data) }
二、App Router 方案(Next.js 13+)
若使用App Router的ISR配置,可结合客户端组件的路由事件监听实现:
- Server Component 配置ISR
在app/[route]/page.js中设置重新验证规则:
export async function generateStaticParams() { // 生成静态路由参数(按需实现) } export default async function Page({ params }) { const data = await fetchTargetData(params) return <ClientContent data={data} /> } // 配置ISR重新验证时间 export const revalidate = 60
- Client Component 监听更新状态
创建客户端组件,通过路由refresh事件感知页面重新验证:
'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' export default function ClientContent({ data }) { const [isRevalidating, setIsRevalidating] = useState(false) const router = useRouter() useEffect(() => { const handleRefresh = () => { setIsRevalidating(true) // 页面更新完成后隐藏加载器(可根据实际调整延迟时间) setTimeout(() => setIsRevalidating(false), 1000) } router.refresh() // 初始同步一次 router.addEventListener('refresh', handleRefresh) return () => router.removeEventListener('refresh', handleRefresh) }, [router]) return ( <div> {isRevalidating && <div className="loader">正在更新内容...</div>} <div>{/* 渲染页面数据 */}</div> </div> ) }
三、核心逻辑说明
- Next.js的ISR默认是后台静默生成新页面,用户当前访问的页面会先返回旧内容,直到新页面生成完成,因此无法直接通过服务端渲染参数传递“正在重新验证”的状态到当前页面。
- 借助SWR/React Query这类缓存库的
isValidating/isFetching状态,可监听客户端数据重新验证的过程,进而显示加载器。 - App Router中,通过
router.refresh()和refresh事件,可感知页面内容的更新状态,从而控制加载器的显示与隐藏。
内容的提问来源于stack exchange,提问作者underfrankenwood
相关产品推荐
相关产品推荐

