本文前提是你拥有
React
基础, 旨在帮你用Node.js构建服务端渲染的网站。
帮助你开发博客、官网、支持SSR。
NextJs是什么?
Next.js是一个React开发框架。
它为你的React应用程序提供了额外的解决方案和内置功能(包括但不限于):
- 直观的、 基于页面 的路由系统(并支持 动态路由)
- 预渲染。支持在页面级的 静态生成 (SSG) 和 服务端端渲染 (SSR)
- 自动代码拆分,提升页面加载速度
- 具有经过优化的预取功能的 客户端路由
- 内置 CSS 和 Sass 的支持,并支持任何 CSS-in-JS 库
- 开发环境支持 快速刷新
- 利用 Serverless Functions 及 API 路由 构建 API 功能
- 完全可扩展
使用它你可以快速的开发React应用程序而不用去捣鼓各种开发工具。
创建Next.js项目
项目创建与2023/6/15
使用的部分版本为: Node.js 16.8、React 18.2.0、TypeScript 5.1.3
安装Next.js
## Installation
npm create-next-app@latest
# or
yarn create next-app
What is your project named? -- my-app
项目名称
Would you like to use TypeScript with this project? -- Yes
项目是否使用TS
Would you like to use ESLint with this project? -- Yes
项目是否使用ESLint
Would you like to use Tailwind CSS with this project? -- Yes
项目是否使用TailwindCSS
Would you like to use
src/
directory with this project? -- Yes项目是否使用
src/
目录
Use App Router (recommended)? -- Yes
项目是否使用路由(推荐使用)
Would you like to customize the default import alias? -- No
是否要自定义默认导入别名(Yes or No 都可)
What import alias would you like configured? -- @/*
若要自定义默认导入别人则会出现此项用于配置(默认配置
@/*
)
安装完毕后你有了一个Next.js项目,现在让我们进入项目:
用 VsCode
打开项目,你的目录结构应该如下:(.next文件夹在项目启动后会自动生成)
运行 npm run dev
或 yarn dev
来启动开发服务端, 默认访问地址为 http://localhost:3000
。
打开 http://localhost:3000,你的页面默认如下所示:
恭喜!你的Next.js应用程序创建成功!
目录介绍
创建页面及路由
基础路由
src/
目录下 app/
和 pages/
目录选择一个作为你的路由目录,你的所有路由都与此有关。
在NextJs13版本中 默认使用
app/
目录,不同的目录配置也不相同
app/
目录下默认 page.tsx
文件就是你的根路径展示文件。
app/
目录中的 每一个定义了page
文件的文件夹 都是你的路由。
在 app/
目录中创建一个命名为app/dashboard/page.tsx
的文件并导出(export)一个如下所示的React组件:
// app/dashboard/pages.tsx
const DashBoard = () => {
return <div>这是DashBoard页面</div>;
}
export default DashBoard;
通过 /dashboard 路径,你可以访问该页面。
组件层次结构
layout
该文件作为你的页面布局,在
app/layout.tsx
中,你始终应该创建一个<html>
和<body>
标签,这是必需的!你的全局样式表应该在此处导入。
page
这里是你的页面内容,尝试更改内容,你的页面对应处也会更改。
template
这个作为你的模板文件
error
这个是你的报错处理
loading
加载时的loading态
not-found
没找到页面时的展示页面
route
返回路由地址
对应的层次结构如下所示
在一个嵌套路由中,一个组件将被嵌套在它的父级组件中。
当然,除了特殊文件,你还可以选择将你自己的文件(例如组件、样式、测试等)放在
app/
目录下的文件夹中。但我建议你最好不要这么做,保证路由的清晰程度很重要!
动态路由
动态路由可以通过将文件夹的名称用方括号括起来创建, 例如[id]
或 [slug]
。
在 app/
目录中创建一个命名为app/blog/[id]/page.tsx
的文件并导出(export)一个如下所示的React组件:
// app/blog/[id]/page.tsx
const Page = ({ params }: { params: { id: string } }) => {
return <div>My Post: {params.id}</div>
}
export default Page;
通过 /blog/a 路径,你可以访问该页面。
其中,params
参数为{ id: 'a' }
组件模式
服务端组件和客户端组件有何区别?我该在什么情况下使用?
服务端组件
为什么使用服务端组件?与客户端组件相比,使用它的优势是什么?
服务端组件允许开发人员更好地利用服务端基础设施。例如,您可以将数据获取移到离数据库更近的服务端上,并保留以前会影响服务端上客户端JavaScript包大小的大型依赖项,从而提高性能。
服务端组件使编写React应用程序感觉类似于PHP或Ruby on Rails,但具有React的功能和灵活性以及用于模板UI的组件模型。
async function getData() {
const res = await fetch('https://api.example.com/...')
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
// Recommendation: handle errors
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data')
}
return res.json()
}
export default async function Page() {
const data = await getData()
return <main></main>
}
要在TypeScript中使用async Server组件,请确保你使用的是TypeScript 5.1.3或更高版本和@types/react 18.2.8或更高版本。
使用服务端组件,初始页面加载速度更快,并且减少了客户端JavaScript包的大小。基本客户端运行时的大小是可缓存和可预测的,并且不会随着应用程序的增长而增加。
只有在通过客户端组件在应用程序中使用客户端交互时,才会添加额外的JavaScript。
当用Next.js加载路由时,初始HTML就会在服务端端呈现。然后这个HTML在浏览器中逐渐增强,允许客户端接管应用程序并添加交互性,通过异步加载Next.js和React客户端运行时。
为了更容易过渡到服务端组件,App Router中的所有组件默认都是服务端组件,包括特殊文件和配置的组件。这允许您自动采用它们,而不需要额外的工作,并获得开箱即用的出色性能。你也可以通过在文件顶部 use client
指令选择加入客户端组件。
客户端组件
客户端组件使您能够向应用程序添加客户端交互性。
在Next.js中,它们在服务端上预渲染,并在客户端上进行渲染。您可以将客户端组件视为Pages Router中的组件一直以来的工作方式。
使用 use client
use client
指令是一种约定,用于声明服务端组件和客户端组件模块图之间的边界。
在文件的顶部,在import
的上方加入 use client
即可启用,一旦启用则其中的所有导入的模块,包括子组件都被视为客户端包的一部分。
使用场景
你需要做什么 | 服务端组件 | 客户端组件 |
---|---|---|
获取数据 | ✔️ | ❌ |
直接访问后端资源 | ✔️ | ❌ |
将敏感信息保存在服务端上(访问令牌、API密钥等) | ✔️ | ❌ |
在服务端上保持大量的依赖性/减少客户端的JavaScript | ✔️ | ❌ |
增加互动性和事件监听器(onClick(), onChange()等) | ❌ | ✔️ |
使用状态和生命周期效果(useState()、useReducer()、useEffect()等) | ❌ | ✔️ |
使用仅适用于浏览器的API | ❌ | ✔️ |
使用依赖于状态、效果或纯浏览器API的自定义钩子 | ❌ | ✔️ |
使用React类组件 | ❌ | ✔️ |
使用建议
服务端组件和客户端组件可以组合在同一个组件树中。
在客户端,React呈现客户端组件,并在服务端组件的呈现结果中插入插槽,合并在服务端和客户端上完成的工作。
与其将整个文件做成一个客户端组件,不如尽可能的将交互式组件抽离,这意味着你不必将所有JavaScript组件发送到客户端。
路由页面跳转
现在你已经能够创建页面及路由,也了解了服务端组件和客户端组件的区别,接下来让我们在路由中跳来跳去~
服务端跳转\<Link>
\<Link>是一个React组件,它扩展了HTML \<a>元素,在路由之间提供预取和客户端导航。这是Next.js中导航路由的主要方式。
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
客户端跳转 useRouter
useRouter钩子允许你以编程的方式改变客户端组件中的路由。
建议你始终使用\<Link>组件进行路由跳转,除非你有使用useRouter的特殊需求。
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
配置项目
SSR
元数据 Metadata
Next.js有一个元数据API,可以用来定义你的应用元数据(例如,HTML head元素中的meta和link标签),以提高SEO和网络可共享性。
在layout.tsx
或page.tsx
文件中导出静态元数据对象或动态generateMetadata
函数。
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
// or
export async function generateMetadata({ params, searchParams }: Record<string, any>) {
...
return {
title: '...',
description: '...',
keywords: '...',
};
}
总结
本文通过创建一个Next.js应用程序以及所需的页面、目录、路由、组件模式、元数据的配置等介绍了其基本内容。
如果你即将构建服务端渲染应用,不妨试试Next.js, 相信绝对不会让你失望!