如何使用 Next.js 中的服务器端渲染将我的应用程序划分为可重用的组件

se2*_*2as 6 javascript reactjs next.js

我对编写 Next.js 应用程序感到困惑,当我有可重用的组件和<Link>s 导航到应用程序的其他区域时,该应用程序将在服务器端呈现页面。

文档说

  • getInitialProps(SSR)页面调用,不为组件调用”
  • componentWillMount执行服务器端,它的客户端只渲染
  • <Link> 标签只是客户端导航,因此它导航到的“页面”在客户端呈现

我的问题

我不清楚以下几点:

  1. 如何将您的应用程序分解为可重用的组件以保持服务器端渲染?
  2. 如果<Link>应用程序的其他页面有s,其他页面如何在服务器上呈现?
  3. 如果<Link>s 是客户端,这当然意味着只有初始页面会在服务器端呈现,那么用 Nextjs 而不是普通的 React 编写应用程序有什么意义呢?
  4. 如果getInitialProps只为页面调用,当然这意味着页面getInitialProps必须为在其页面上呈现的任何数据执行所有服务器调用,然后发送到子组件,这肯定非常慢。如果一个页面包含一个项目列表,将会有一个服务器调用来获取项目列表,对于列表中的每个项目,需要一个调用来获取项目详细信息,另一个调用来获取项目图片。这是在呈现页面之前的大量服务器调用。

我的应用程序

我认为用我想要做的事情的示例应用程序来说明我的问题会更容易。

  • 我的应用程序有几个页面:Tab-1、Tab-2、Tab-3、Tab-4 以及 Tab-1 和 Tab-2 中列出的项目的详细信息页面等。
  • 我的应用程序中的每个页面都有相同的布局、页眉区域、标签栏、页面内容和页脚
  • 单击选项卡栏中的项目时,您可以导航到我的应用程序中的其他页面
  • 每个选项卡都包含不同类别的项目列表,单击列表中的项目会将用户带到该项目的详细信息“页面”

这是我的应用程序的图形表示。

应用图形表示

项目结构

所有页面都使用layout-template添加页眉和页脚的主要结构,然后使用组件在页面中间添加自己的内容

|- pages
     |- index.js  (i.e. tab-1)
     |- tab2.js
     |- tab3.js
     |- tab4.js
     |- aitem
          |- [id].js
     |- numitem
          |- [id].js
|- Components
     |- layout-template.js --- needs data to pass to header/footer
     |- header.js
     |- footer.js
     |- AlphabetList --- needs data
     |- AlphabetListItem --- needs data
Run Code Online (Sandbox Code Playgroud)

下面是我的组件示例,展示了它们如何组成我的应用程序。请参阅他们必须从服务器获取数据的一些组件。

由于它们是组件,因此它们在 中获取数据componentWillMount,这意味着该组件不会呈现服务器端。因此这似乎完全违背了编写 Next.js 的初衷。

Component = layout_template.js 需要从服务器获取数据传递给页眉和页脚

布局模板图像

Component = header.js 只包含 JSX

标题

Page = Index.js (URL= "/" or "/index") 不从服务器获取任何数据,只指定 JSX

索引页

Component = AlphabetList.js 从服务器获取字母项目列表并使用另一个组件呈现它

字母项目

Component = AlphabetListItem.js从服务器获取项目的图像然后呈现它。单击此组件后,应用程序将转到项目的详细信息页面

获取字母项目的图像

Page = AlphabetItemDetails.js ( URL = "aitem/[id]") 从服务器获取有关该项目的附加信息并呈现该项目的填充详细信息

获取额外信息

我如何构建我的代码?

  • 对于在服务器端呈现的主要布局/页眉/页脚,我是否必须复制代码才能getInitialProps每个页面中获取徽标?即在 index.js、tab2.js、tab3.js、tab4.jsaitem/[id].jsnumitem/[id].js? 这似乎与任何不复制代码而是引入可重用代码的体面代码设计背道而驰。
  • 对于要在服务器端呈现的页面中的所有数据,我是否必须获取所有列表项,然后获取页面中的每个项的详细信息和图像 URL getInitialProps

小智 2

首先,选项卡不必是新页面。选项卡可以是组件。

在主页(index.js)上,您可以将使用 getInitialProps 获取的数据传输到带有 prop 的组件。

您还可以通过 Layout 通过 prop 向 header 和 footer 等组件发送数据。对于页眉中的徽标,您可以在页面文件夹中创建 _app.js 并使用 getInitialProps 从此处提取数据,而不是在每个页面上再次提取数据。

欲了解更多详细信息,您可以访问此页面https://nextjs.org/docs/getting-started

  • 在 `_app.js` 中使用 `getInitialProps` 时要小心。我建议仅当您的应用程序中的每个页面都有阻止数据要求时才这样做。这会禁用执行自动静态优化的能力,导致应用程序中的每个页面都在服务器端呈现。 (3认同)