NextJS:使用 Next.js 14 实现并行路由以进行选项卡导航而无需重新渲染页面?

问题描述 投票:0回答:1

我正在使用 Next.js 14 开发一个项目,我正在尝试实现一个选项卡导航系统,其中每个选项卡对应于不同的路线(

/resume
/source
)。目标是在这些选项卡之间导航,而无需在每次路线更改时重新渲染页面。

在这些页面中,我使用

react-pdf
库 (https://github.com/wojtekmaj/react-pdf) 来显示 PDF 文档。当我在选项卡之间导航时,我希望 PDF 文档保持显示状态而不重新加载。但是,我仍然希望更改导航 URL 以反映活动选项卡。

这是我当前设置的简化版本:

// packages/client/src/app/editor/[uuid]/@content/source/page.tsx
import React from 'react';
import SourceDocument from '@/app/editor/[uuid]/@content/source/components/source-document';

export default async function SourcePage({ params: { uuid } }: SourcePageProps): Promise<JSX.Element> {
  // ...fetching data...
  return <SourceDocument url={resumeSourceFile.url} />;
}

// packages/client/src/app/editor/[uuid]/@content/source/components/source-document.tsx
import React from 'react';
import { DocumentViewer } from '@/components/document-viewer';

const SourceDocument = ({ url }: SourceDocumentProps): JSX.Element => {
  // ...state and handlers...
  return <DocumentViewer onLoadSuccess={onLoadSuccess} numPages={numPages} file={url} />;
};

export default React.memo(SourceDocument);

我尝试使用

React.memo
来防止不必要的重新渲染,但在这种情况下似乎不起作用,因为当路由更改时组件会被卸载并重新安装。

我想实现以下目标:

  1. 当我从
    /resume
    导航到
    /source
    (或反之亦然)时,如果我之前访问过该页面,它不应该重新渲染,而是提供完全相同的内容。
  2. 导航 URL 应更改以反映活动选项卡。
  3. 如果我硬重新加载页面,那么它应该重新渲染。

任何关于如何在 Next.js 14 中实现这一点的建议将不胜感激。预先感谢!

next.js caching next.js13 app-router
1个回答
0
投票

您想要实现的是持久布局。如果您想避免在作为并行路线在两个选项卡之间导航时重新渲染,您的

resume
source
组件都必须共享相同的父布局文件。

要创建并行路线,您需要使用

@folder
约定将它们定义为槽。例如,您将在
@resume
中包含
@source
documents
。文件夹结构应如下所示:

├── app
│   ├── (custom-route-group)
│   │   ├── documents
│   │   │   ├── @resume
│   │   │   │   ├── client.js
│   │   │   │   └── page.js
│   │   │   ├── @source
│   │   │   │   ├── client.js
│   │   │   │   └── page.js
│   │   │   ├── layout.js
│   │   │   └── page.js

// The parent layout file houses both the resume and source components (also called slots in this case). The slots are then automatically passed to the layout in the same route segment as its props.

export default function DocumentLayout({ children, resume, source }) {
  return (
    <div>
      <main>
      <div>{ children }</div>
      <div>{ resume }</div>
      <div>{ source }</div>
      </main>
    </div>
  );
}

拥有路线组(例如

(custom-route-group)
)并不是必须的。它是可选的,它只是帮助组织您的应用程序文件夹。

我假设您在 Next.js 中使用 App Router。这个解决方案在页面路由器中会略有不同。

如果您有任何疑问,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.