关于Next.js完整的初学者指南

803 阅读6分钟

我一直在不停地使用Create React App来搭建React应用的支架,我很喜欢它。不过最近,我越来越多地使用Next.js来做这些应用。它有一堆伟大的功能,如路由和服务器端渲染,为终端用户和开发人员提供了惊人的体验。

Next.js是一个React元框架,这意味着它是一个建立在React之上的框架,执行更多的结构,并给你更多的能力:如服务器端渲染、路由、捆绑等等。在这篇文章中,我们将介绍如何开始使用Next.js,SSR与SSG,以及路由。

如果你以前没有使用过React,请阅读我的React入门教程,然后再来这里做这个教程你首先需要一个React基础。

创建一个Next.js应用程序

我们要创建一个在主页上列出颜色的应用程序。每一个都链接到一个颜色页面,显示该颜色的信息!

首先,我们将使用CLI初始化一个Next.js应用。这与大多数应用程序初始化脚本的工作原理一样,它为你生成了一堆启动文件:

$ npx create-next-app color-pages
$ cd color-pages

然后,我们将启动开发服务器 -- 它内置了热重载功能,并在生成的主页上提供了文档链接:

$ npm run dev

现在,我们可以开始写代码了我们将首先创建一个带有颜色的静态json文件。为颜色创建一个目录,然后在里面添加一个颜色文件。然后添加颜色!

mkdir data
touch data/colors.json

我使用了一堆Pantone的年度颜色来创建这个,请随意复制如果你自己制作,请确保使用这种结构,以便代码的其余部分能够工作:

// data/colors.json
[  { "name": "Illuminating", "hex": "#F5DF4D" },  { "name": "Classic Blue", "hex": "#0f4c81" },  { "name": "Living Coral", "hex": "#FA7268" },  { "name": "Ultra Violet", "hex": "#5f4b8b" },  { "name": "Greenery", "hex": "#88b04b" },  { "name": "Rose Quartz", "hex": "#F7CAC9" },  { "name": "Marsala", "hex": "#B57170" },  { "name": "Radiant Orchid", "hex": "#b067a1" }]

路由

现在,我们要做的是color 页面。使用Next.js,如果你在pages 文件夹中创建一个文件,它就会将其变成一个路由。因此,你可以创建about.js ,以获得一个/about 页面 --index.js 中的例外,它的路由是/ 。你也可以建立文件夹来创建路由,如/blog/my-post-title 。如果你把文件名放在[] ,那么括号里的名字就成了参数名。我们想为上述数组中的每种颜色创建路由,所以我们将创建一个名为[color].js 的文件 -- 这将使我们能够一次性为 "经典蓝"、"超紫 "等动态创建一个页面 -- 无需为每种颜色创建单独的.js文件。

$ touch pages/[color].js

getStaticPaths

现在,让我们创建我们的getStaticPaths() 函数。Next.js寻找这个函数,以便为该模板生成所有的静态页面--在我们的例子中是我们的颜色。我们想按照相同的格式为我们的每种颜色建立一个页面,但不必对每个页面进行硬编码。

首先,将导入我们的colors 数组。然后,在我们的函数中,我们将循环浏览它们,并为每个路径参数命名。在这种情况下,我们的路由参数是color ,以匹配我们文件名中的[] 里面的参数名称。我们希望我们的路由中的颜色与每个颜色的名称相匹配--所以/Marsala 将渲染显示马沙拉色的页面。

最后,我们将以Next.js正在寻找的格式返回所有的颜色。我们将把它们放在一个对象中,并将fallback 设置为false -- 这将使你进入/hotpink (不在我们数组中的颜色),你会得到一个404页面

// [color].js
// import the colors array
import colors from '../data/colors.json'

export async function getStaticPaths() {
  // loop through the colors array
  const paths = colors.map(color => ({
    // return an object with params.color set to the color's name
    params: { color: color.name }
  }))

  // Paths will look like this:
  // [
  // { params: { color: 'Marsala' } },
  // { params: { color: 'Illuminating'} }
  // ...
  // ]
  return { paths, fallback: false }
}

在大多数较大的用例中,你可能想从你的文件系统中读取文件(如博客文章的markdown文件)或从外部API中获取数据。你可以在getStaticPaths ,为你的应用程序生成路径,这两个任务都可以做。

getStaticProps

现在,我们将定义Next.js正在寻找的getStaticProps 函数。这个函数将为页面的React组件提供props 。在我们的用例中,我们只想要当前页面上的颜色信息。所以,/Marsala 的页面得到的数据是{ "name": "Marsala", "hex": "#B57170" } -- 而不是所有其他的颜色!

getStaticProps 函数获得传递给它的参数,在我们的例子中是颜色名称。对于/Marsala 页面来说,参数看起来就像{ color: 'Marsala' } -- 就像我们在getStaticPaths 函数中创建的那样。在我们的例子中,我们将在我们的数组中找到名称与参数中的颜色相符的颜色。然后我们将返回数据 -- Next.js要求返回数据嵌套在{ props }中。

// [color].js
export async function getStaticProps({ params }) {
  // find the info for just one color
  const color = colors.find(color => color.name === params.color)
  // return it in the necessary format.
  return { props: { color } }
}

在一个更大的应用程序中,你可能会从API中提取getStaticProps ,以便获得一个项目的信息,或者你可能需要只获取一个markdown文件来渲染一篇博客文章。

为页面制作模板

现在我们进入了有趣的部分!创建React组件,对页面进行模板化处理!我们在getStaticProps 中创建的props对象将由Next.js传递给该组件--我们只需要在页面上渲染数据即可我们将使用十六进制代码为页面添加背景色,并渲染颜色名称。

// [color.js]
export default function Color({ color }) {
  return <div className='color-page' style={{ backgroundColor: color.hex }}>
    <h1>{color.name}</h1>
  </div>
}

我将CSS文件替换为以下内容,使页面看起来更好一些。

/* global.css */
html,
body, #__next, .color-page {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
  top: 0px;
  position: absolute;
  display: block;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

.color-page {
  display: flex;
  justify-content: center;
  align-items: center;
}

链接组件

现在,我们需要做的是使用Link 组件,从主页链接到每种颜色的页面。我们将用颜色的列表更新index.js

我们将在这个Home 组件中使用两个Next.js特定的组件--LinkHead<Link> 允许你做客户端的路由转换,这将使用户的页面转换更顺畅。我们将用它来代替,否则就像a 标签一样。

<Head> 组件允许我们从该组件内向htmlhead 标签插入数据。我们将从那里更新页面的标题和元标签!

// index.js
import Head from 'next/head'
import Link from 'next/link'

import colors from '../data/colors.json'

export default function Home() {
  return (
    <div>
      <Head>
        <title>Colors!</title>
        <meta name="description" content="App that displays pretty colors to learn Next!" />
      </Head>
      {colors.map(color => (
        <Link href={`/${color.name}`}>
        <h2>{color.name}</h2>
        </Link>
      ))}
    </div>
  )
}

SSR vs. SSG

我们刚刚建立了一个静态生成的Next.js应用程序,这意味着数据只在构建时获取。如果我们的颜色来自于API,并且我们已经建立并部署了我们的网站,那么我们的应用程序将不会随着API的变化而更新(例如添加了2022年的颜色)。对于许多应用程序来说,这完全没有问题。一个博客不需要太频繁地更新内容。

SSG(静态网站生成)允许Next.js在网站建设时为每个页面生成HTML。然后,这些页面可以被CDN缓存,导致一个超级性能的网站。

也就是说,有时你需要一个动态更新的网站,这就是服务器端渲染的作用。SSR(服务器端渲染)允许你仍然在服务器端渲染HTML,但在用户对页面提出的每个请求时都进行渲染,而不是在构建时。

为了使用SSR而不是SSG,我们将用getStaticPropsgetStaticPaths 替换成getServerSideProps 。请注意,下面的例子不会起作用,因为我们实际上并没有创建一个API!

export async function getServerSideProps({ params }) {
  // Make a request to get data about the color via our API
  const res = await fetch(`http://www.color-api.com/${params.color}`)
  const color = await fetch.json()
  // return the data as props that will be passed to the Color component
  return { props: { color } }
}

如果你想阅读更多关于SSR与SSG的内容,我有一篇完整的博文来介绍两者的区别。

部署

现在你已经写好了一个Next.js应用程序,你需要让它上线。AWS Amplify支持部署SSR和SSG Next.js应用程序,而无需在您的终端进行任何额外配置。

如果你正在创建一个静态生成的Next.js应用程序,请进入你的package.json 文件,将你的build 脚本改为next build && next export 。如果你正在创建一个服务器端渲染的应用程序,你不需要改变任何东西Next.js为你生成的脚本将是你需要的东西。

"scripts": {
  "dev": "next dev",
+ "build": "next build && next export",
  "start": "next start"
},

然后,在你选择的git提供商上创建一个仓库,并将你的代码推送给它:

  1. 如果你还没有AWS账户,请创建一个账户

  2. 导航到Amplify控制台

  3. 点击橙色的connect app 按钮

  4. From your existing code 菜单中选择GitHub ,然后点击继续

Amplify interface with different remotes

  1. 键入你刚刚创建的GitHub repo的名称(它应该是自动填充的!),然后点击next

Amplify interface with name of repo

  1. 构建设置将自动填充,因此你可以直接点击next 上的Configure build settings
  2. 点击Save and deploy

总结

Next.js有一个惊人的开发者体验。它有很好的错误信息、全面而易懂的文档,而且功能超级强大,只是比普通的React应用多做一点。我希望这个教程对你有帮助

如果你对学习另一项技能感兴趣,这里有一个教程,介绍如何用Amplify将你的Next.js前端变成一个全栈应用