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

使用router.refresh()时Suspense fallback未显示的问题

问题解决:点击刷新按钮时显示Suspense的fallback内容

问题原因

router.refresh() 触发页面服务器组件重新渲染时,Next.js 默认不会触发客户端的 Suspense fallback 展示——这个 fallback 主要在初始服务端渲染或客户端路由跳转时生效,页面内的刷新操作不会主动触发加载状态的显示。

解决方案:手动管理加载状态

我们可以通过客户端状态控制加载状态,在点击刷新按钮时显示骨架屏,直到刷新完成后隐藏。

方案1:基础状态控制

步骤1:修改 Home 页面为客户端组件,添加加载状态

'use client'
import { useState } from 'react'
import RefreshBtn from './RefreshBtn'
import NoteSkeleton from './NoteSkeleton'
import Feed from './Feed'

const Home = () => {
  const [isRefreshing, setIsRefreshing] = useState(false)

  return (
    <>
      <RefreshBtn 
        onStartRefresh={() => setIsRefreshing(true)} 
        onFinishRefresh={() => setIsRefreshing(false)} 
      />
      {isRefreshing ? <NoteSkeleton /> : <Feed />}
    </>
  )
}
export default Home

步骤2:修改 RefreshBtn 组件,传递状态回调

'use client'
import { useRouter } from 'next/navigation'

function RefreshBtn ({ onStartRefresh, onFinishRefresh }) {
  const router = useRouter();

  const handleBtn = async () => {
    onStartRefresh()
    await router.refresh()
    // 因router.refresh()无返回值,可根据接口响应速度调整延迟时间
    setTimeout(() => onFinishRefresh(), 300)
  }

  return (
    <button onClick={handleBtn}>Refresh</button>
  );
};

export default RefreshBtn;

方案2:结合 React 过渡 API 保留 Suspense 写法

'use client'
import { useState, useTransition } from 'react'
import RefreshBtn from './RefreshBtn'
import NoteSkeleton from './NoteSkeleton'
import Feed from './Feed'

const Home = () => {
  const [isPending, startTransition] = useTransition()
  const [refreshKey, setRefreshKey] = useState(0)

  const handleRefresh = () => {
    startTransition(() => {
      setRefreshKey(prev => prev + 1)
    })
  }

  return (
    <>
      <RefreshBtn onRefresh={handleRefresh} />
      <Suspense fallback={<NoteSkeleton />}>
        {/* 通过key变化强制Feed重新渲染,触发Suspense fallback */}
        <Feed key={refreshKey} />
      </Suspense>
    </>
  )
}
export default Home

同步修改 RefreshBtn:

'use client'

function RefreshBtn ({ onRefresh }) {
  return (
    <button onClick={onRefresh}>Refresh</button>
  );
};

export default RefreshBtn;

内容的提问来源于stack exchange,提问作者Elher Encarnacion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:35:30