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

Next.js路由重新验证时如何显示加载器?是否存在isRevalidating标识?

在Next.js中ISR重新验证时显示加载器的实现方案

首先明确:Next.js 本身没有直接暴露名为isRevalidating的内置标识,但可以通过不同路由方案(Pages Router/App Router)结合数据缓存库或自定义逻辑实现需求。

一、Pages Router 方案(适配你的getStaticProps场景)

结合SWR库监听数据重新验证状态,以此控制加载器显示:

  1. 安装SWR
npm install swr
  1. 页面组件改造
    不再直接通过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>
  )
}
  1. 对应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配置,可结合客户端组件的路由事件监听实现:

  1. 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
  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:42:12