如何使用NextJS 进行展示的渲染

519 阅读5分钟

图片描述

渲染类型

支持三种渲染类型。那些是:

1.客户端渲染

加载应用程序后,将在客户端获取任何所需的数据。获取所有内容后,将生成内容并显示在 UI 中。这也是为什么它被称为客户端的原因,因为所有的工作都在客户端完成。

2.服务端渲染

这个与客户端非常相似,但明显的区别是一切都发生在服务器上。一旦用户发出请求,在服务器上准备好所有数据并生成内容,并作为响应发送给用户。加载并显示该内容后,将加载所有 JavaScript,并在称为 hydration 的过程中附加所有侦听器。要使用这种类型的呈现,您需要公开 getServerSideProps 函数,您可以在该函数中获取组件所需的所有数据。

3.静态侧生成

Static Side Generation 是一种特殊类型的服务器端渲染。不同之处在于渲染不会在请求时发生,而是在构建期间发生。也许您有一些想要准备好的页面,但它们不会经常更改,那么您可以在构建期间生成它们的内容,然后只为已经准备好的页面提供服务。也有可能通过使用增量静态重新生成在构建后生成新内容,但目前这是一个更高级的话题。要使用这种类型的渲染,您需要公开 getStaticProps 函数,您可以在其中获取所有必需的道具。

例子

在接下来的三个部分中,我将展示每种类型的渲染是如何工作的。首先,您将看到一个小组件显示一个人的名字和姓氏,然后是每种渲染类型以及如何加载数据。

export default function Person() {
  const person = {
    firstName: "John",
    lastName: "Doe"
 };

 return (
   <>
     Hello {person.firstName} {person.lastName}!
   </>
   )
 }

以上是我将在其余示例中使用的起始页组件。如您所见,它非常简单。它有一个带有个人详细信息的硬编码对象,并以 HTML 格式显示它们。对于其余示例,我将使用 API 端点 /api/person 来加载该数据。

客户端渲染

在客户端执行所有操作时,有多种方法可以加载数据。NextJS 团队推荐的方法是使用 SWR npm 包中的 useSWR 挂钩。下面的代码片段是这样做的一个例子。

import useSwr from 'swr';

export default function ClientPerson() {
  const fetcher = (...args) => fetch(...args).then((res) => res.json())
  const { data, error } = useSwr('/api/person', fetcher)

  if(error) return <div>error</div>;
  if(!data) return <div>loading</div>;

  return (
    <>
      Hello {data.firstName} {data.lastName}!
    </>
  )
}

当您使用该挂钩时,它会返回一个包含一些属性的对象,其中一些是数据和错误,但也有其他的。此外,对于不想运行的情况,您可以通过将 URL 的值设置为 null 来有条件地运行它。这个钩子还有其他好处,比如缓存。如果组件被重新渲染但获取的值没有改变,它将从缓存中加载响应。

要查看此类渲染的效果,您可以打开检查器工具。在网络选项卡中,您首先会看到正在加载的页面,然后是从 API 获取个人数据的额外请求。

除了这个钩子,你可能还想使用常规的 fetch。这样做的问题是您需要将它包装到类似 useEffect 挂钩的东西中。原因是所有 NextJS 组件都可能在服务器上呈现,并且不应在初始呈现时执行特定于浏览器的功能。

服务器端渲染

在服务端渲染时,如果你的组件不依赖数据,你可以保持原样。但如果是这样,这就是本示例的重点,您需要导出 getServerSideProps 函数,该函数返回一个将作为组件道具传递的对象。

export default function ServerPerson({ person }) {
  return (
    <>
      Hello {person.firstName} {person.lastName}!
    </>
  )
}

export async function getServerSideProps(context) {
  return {
    props: {
      person: { firstName: "John", lastName: "Doe" }
    }, // will be passed to the page component as props
  }
}

正如您在上面的代码示例中看到的,getServerSideProps 是一个异步函数。这就是原因。您返回的数据可以取自一些异步源,例如数据库或其他 API。

但现在让我们介绍一下它在底层是如何工作的。如果您检查检查员的网络选项卡,这次将只是一个请求。当用户请求命中服务器时,道具首先准备好。一旦完成,这些将被发送到组件并生成最终的 HTML。该 HTML 作为响应返回,一旦显示,就会运行一个称为 hydration 的过程。这是所有点击处理程序和其他侦听器都绑定到元素的地方。

静态网站生成

静态生成有点类似于服务器端渲染,但有一些不同。第一个区别是它使用的功能。服务器端使用 getServerSideProps,而这个使用 getStaticProps。

export default function PersonStatic({ person }) {
  return (
    <>
      Hello {person.firstName} {person.lastName}!
    </>
  )
}

export async function getStaticProps(context) {
  return {
    props: {
      person: { firstName: "John", lastName: "Doe" }
    }, // will be passed to the page component as props
  }
}

看着这个你可能想知道,有什么区别,为什么使用这个而不是其他功能?原因是内容何时生成。对于服务器端呈现,我提到内容生成是根据请求完成的,这个是在应用程序构建时完成的。一旦用户发出请求,内容已经存在并立即返回。
这也可能会提示您何时使用哪种类型的渲染。如果您的内容是动态的并且会发生变化,那么服务器端呈现可能是更好的选择。如果您有一些不会改变的内容,那么静态生成可能会更好。

此外,还有一些更高级的静态生成选项。上面,我给了你一个固定页面的例子,但你也可以为动态路由做。假设有一个很少更改的项目列表。在这种情况下,您可以公开另一个函数 getStaticPaths,它将公开您想要预呈现的路由列表。其他人可能会返回 404,或者您可能会让他们表现得像服务器端一代。