javascript Next.js 13导航路由器刷新保留状态

z5btuh9x  于 2023-06-28  发布在  Java
关注(0)|答案(1)|浏览(128)

我有下面这个组件,它包含在一个服务器组件中,用于获取数据并呈现它。可以看到,我在单击时调用router.refresh(),因此它将重新运行该页面并重新获取数据。确实如此,但问题是Nextjs一直保留这个状态,所以当我调用setRefreshing(true)时,即使服务器组件重新运行刷新状态仍然是true。

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

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

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

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

useEffect在刷新后也没有运行,所以我也不能将其设置为false。我找到了一个解决方法,将数组属性传递给组件,然后它将重新运行useEffect(() => {...}, [serverHackyProp])

<Refresh inProgress={[false]} />

const [[refreshing], setRefreshing] = useState(inProgress)
const router = useRouter()

useEffect(() => {
  setRefreshing(inProgress)
}, [inProgress])

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

它的工作原理是因为传递的数组总是有一个新的引用,所以每次服务器重新运行时,useEffect都会运行。但我不喜欢这样做,除非这是我最后的选择,但我找不到一种方法来setRefreshing(false)后,路由器刷新(服务器重新获取)。

fdbelqdn

fdbelqdn1#

这个问题的一个简单解决方案是让数据获取函数返回一些随机值作为响应的一部分,并将该随机值用作Refresh组件的键。这样,每次刷新服务器端数据时,Refresh组件都将被拆除并重新创建。

// setting revalidate to 0 just for the testing purpose
export const revalidate = 0;

async function getData() {
  return { data: ..., sid: Math.random() };
}

export default async function Page() {
  const data = await getData();

  return (
    <>
      <Refresh key={data.sid} />
      ...
    </>
  );
}

相关问题