likes
comments
collection
share

Next.js 12迁移至Next.js13版本 升级指南

作者站长头像
站长
· 阅读数 11

一、前置

详见文档: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。

Next.js 12迁移至Next.js13版本  升级指南

4. 完整删除/pages目录

5. 此时,文件目录如下:

Next.js 12迁移至Next.js13版本  升级指南

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
评论
请登录