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

Next.js 13导航路由刷新后状态保留问题求助

解决Next.js中router.refresh()后客户端组件状态无法重置的问题

方案1:利用router.refresh()的Promise返回值

router.refresh()本身会返回一个Promise,当刷新操作(包括服务端数据重新获取、客户端页面更新)完成后,Promise会resolve。你可以通过async/await在刷新完成后直接重置状态,这是最简洁的解决方案:

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import Button from './Button'

export default function Refresh() {
  const [refreshing, setRefreshing] = useState(false)
  const router = useRouter()

  const handleClick = async () => {
    setRefreshing(true)
    await router.refresh() // 等待刷新完成
    setRefreshing(false)
  }

  return (
    <Button onClick={handleClick}>
      <i className={`bi bi-arrow-repeat text-lg ${refreshing ? 'animate-spin' : ''}`}></i> 
      Refresh
    </Button>
  )
}

方案2:通过服务端传递的唯一标识触发状态重置

如果你的服务端组件每次刷新都会生成一个唯一标识(比如数据的更新时间戳、数据内容的哈希值),可以将这个标识作为props传递给客户端组件,通过useEffect监听该props的变化来重置状态:

服务端组件代码:

// 服务端组件
import Refresh from './Refresh'
import { fetchData } from '@/lib/data'

export default async function ServerComponent() {
  const data = await fetchData()
  // 用数据的更新时间或哈希作为唯一标识
  const dataUpdateId = data.updatedAt || Date.now()

  return (
    <div>
      {/* 渲染数据 */}
      <Refresh dataUpdateId={dataUpdateId} />
    </div>
  )
}

客户端组件代码:

'use client'
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import Button from './Button'

export default function Refresh({ dataUpdateId }: { dataUpdateId: number | string }) {
  const [refreshing, setRefreshing] = useState(false)
  const router = useRouter()

  // 当服务端传递的标识变化时,重置刷新状态
  useEffect(() => {
    if (refreshing) {
      setRefreshing(false)
    }
  }, [dataUpdateId])

  const handleClick = () => {
    setRefreshing(true)
    router.refresh()
  }

  return (
    <Button onClick={handleClick}>
      <i className={`bi bi-arrow-repeat text-lg ${refreshing ? 'animate-spin' : ''}`}></i> 
      Refresh
    </Button>
  )
}

为什么你的临时方案能生效?

你用数组作为props的原因是每次服务端渲染都会创建新的数组引用,导致useEffect的依赖变化,从而触发状态重置。但这种方式不够直观,上面的方案2用业务相关的唯一标识替代无意义的数组,代码可读性和维护性更好。


内容的提问来源于stack exchange,提问作者Doğukan Akkaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:30:23