Next.js 12迁移至Next.js13版本 升级指南
一、前置
详见文档:Upgrading: Version 13 | Next.js (nextjs.org)
检查node版本
使用nvm切换node版本
最低node版本——v16.8
切换 git 分支
git checkout -b migration
升级next版本
npm install next@latest react@latest react-dom@latest
二、 使用app router 替换 /pages
由于next13版本是向后兼容的,所以我们直接使用/pages 路由是可以正常使用的。
1. 将/pages下的所有文件移动到/app目录下
2. 将/app路径下的 index.js 更改为 page.js
3. 按照路由命名规范修改路由文件
使用小括号包起来的文件夹不会进入到实际路由,且每层路由必须使用文件夹包裹page.js \ page.ts\ page.jsx \ page.tsx。
4. 完整删除/pages目录
5. 此时,文件目录如下:
6. 重新运行项目(npm run dev),Next.js将自动生成layouts.js文件
重启项目后,效果如下:
7. 成功将项目迁移至App router路由模式
三、 Migration Next13 routing hooks
App Router模式下,使用3个新hooks
'use client'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
export default function ExampleClientComponent() {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
// ...
}
isFallback
已被删除,因为已被替换。fallback
basePath
已被删除。替代项将不是 的一部分。它尚未得到执行。asPath
已删除,因为已从新路由器中删除了 的概念。isReady
已被删除,因为它不再需要。在静态渲染期间,任何使用useSearchParams()
hook 将跳过预呈现步骤,而是在运行时在客户端上呈现。
详读文档:Functions: useRouter | Next.js (nextjs.org)
四、Migration Data Fetching methods
在app
目录中,我们可以使用服务器组件将数据获取放在 React 组件中。这允许我们向客户端发送更少的JavaScript,同时维护从服务器呈现的HTML。
服务端渲染
以前版本
// `pages` directory
export async function getServerSideProps() {
const res = await fetch(`https://...`)
const projects = await res.json()
return { props: { projects } }
}
export default function Dashboard({ projects }) {
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}
新版本:
// `app` directory
// This function can be named anything
async function getProjects() {
const res = await fetch(`https://...`, { cache: 'no-store' })
const projects = await res.json()
return projects
}
export default async function Dashboard() {
const projects = await getProjects()
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}
访问请求对象
以往版本
// `pages` directory
export async function getServerSideProps({ req, query }) {
const authHeader = req.getHeaders()['authorization'];
const theme = req.cookies['theme'];
return { props: { ... }}
}
export default function Page(props) {
return ...
}
新版本
// `app` directory
import { cookies, headers } from 'next/headers'
async function getData() {
const authHeader = headers().get('authorization')
return '...'
}
export default async function Page() {
// You can use `cookies()` or `headers()` inside Server Components
// directly or in your data fetching function
const theme = cookies().get('theme')
const data = await getData()
return '...'
}
静态站点生成
以往版本
// `pages` directory
export async function getStaticProps() {
const res = await fetch(`https://...`)
const projects = await res.json()
return { props: { projects } }
}
export default function Index({ projects }) {
return projects.map((project) => <div>{project.name}</div>)
}
新版本
// `app` directory
// This function can be named anything
async function getProjects() {
const res = await fetch(`https://...`)
const projects = await res.json()
return projects
}
export default async function Index() {
const projects = await getProjects()
return projects.map((project) => <div>{project.name}</div>)
}
动态路径
以往版本
// `pages` directory
import PostLayout from '@/components/post-layout'
export async function getStaticPaths() {
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
}
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return { props: { post } }
}
export default function Post({ post }) {
return <PostLayout post={post} />
}
新版本
// `app` directory
import PostLayout from '@/components/post-layout'
export async function generateStaticParams() {
return [{ id: '1' }, { id: '2' }]
}
async function getPost(params) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return post
}
export default async function Post({ params }) {
const post = await getPost(params)
return <PostLayout post={post} />
}
其他Data Fetching 更改,详见官方文档:Building Your Application: Data Fetching | Next.js (nextjs.org)
转载自:https://juejin.cn/post/7254361990075072549