通过 useRouter() 导航时,NextJS 13 中不显示暂挂回退

cli*_*ang 3 reactjs next.js next.js13

我正在尝试通过钩子更改路由的 searchParams useRouter。我做了一个最小程序来展示效果。

//page.tsx
import { Suspense } from "react";
import ClientComponent from "./client-component";
import ServerComponent from "./server-component";

export default function Page() {
  return (
    <main>
      <ClientComponent />
      <Suspense fallback={<div>Loading...</div>}>
        <ServerComponent />
      </Suspense>
    </main>
  );
}


// server-component.tsx
// render a datetime string after 2 seconds delay
export default async function ServerComponent() {
  const datetime = new Date().toLocaleString();
  await new Promise((resolve) => setTimeout(resolve, 2000));
  return <div>Server component rendered at {datetime}</div>;
}


// client-component.tsx
// navigate to '/min' with a random searchParam like '/min?q=rs39af'
'use client';

import { useRouter } from "next/navigation";

export default function ClientComponent() {
  const router = useRouter();

  function handleOnClick() {
    //generate a random string
    const random = Math.random().toString(36).substring(7);
    router.push(`/min?q=${random}`);
  }

  return (
    <button onClick={handleOnClick}>change route</button>
  );
}
Run Code Online (Sandbox Code Playgroud)

我期待的行动是

  • 单击按钮更改路线,/min?q=1dk9例如/min?q=8fv0
  • 路由器更新浏览器地址栏中的 URL
  • 显示悬念的后备
  • 加载完成后显示服务器组件

但实际上动作是

  • 单击按钮
  • 服务器组件加载时没有任何变化
  • 服务器组件完成后,浏览器的地址栏更新并呈现服务器组件

但是,我可以看到日期时间确实发生了变化,表明服务器组件已重新渲染,但不起作用Suspense

我需要在加载时查看后备。有人能帮我解决这个问题吗?

小智 7

您使用的 Next.JS 版本是什么?

据此,此问题已在版本 13.3.0中修复- 将 searchParams 添加到叶缓存键:#47312

注意:您的 Suspense 标签需要一个唯一的键来告诉 React/NextJS 内容已发生有意义的更改。

export default function Page({ searchParams } ) {
  return (
    <main>
      <ClientComponent />
      <Suspense key={searchParams.q} fallback={<div>Loading...</div>}>
        <ServerComponent />
      </Suspense>
    </main>
  );
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)