Next.js学习笔记

这是一个用于生产环境的React 框架,Next.js 为您提供生产环境所需的所有功能以及最佳的开发体验:包括静态及服务器端融合渲染、 支持 TypeScript、智能化打包、 路由预取等功能 无需任何配置。

create-next-app

使用 create-next-app创建新的 Next.js 应用程序,它会自动为你设置所有内容。创建项目,请运行:

npx create-next-app@latest
# or
yarn create next-app

如果你希望使用 TypeScript 开发项目,可以通过 --typescript 参数创建 TypeScript 项目:

npx create-next-app@latest --typescript
# or
yarn create next-app --typescript

安装完成后:

注意:直接运行 run start是不能生效的,需要先run build打包才能start。
生产环境下可以运行 npm run dev 或 yarn dev 来启动开发服务器,访问地址为 http://localhost:3000。
通过 http://localhost:3000 地址访问你的应用程序。
编辑 pages/index.js 文件并在浏览器中查看更新。

页面(Pages)

在 Next.js 中,不需要手动设置路由,一个 page(页面) 就是一个从 .js、jsx、.ts 或 .tsx 文件导出(export)的 React 组件 ,这些文件存放在 pages 目录下。每个 page(页面)都使用其文件名作为路由(route)。
在这里插入图片描述

具有动态路由的页面

Next.js 支持具有动态路由的 pages(页面)。例如,如果你创建了一个命名为 pages/posts/[id].js 的文件,那么就可以通过 posts/1、posts/2 等类似的路径进行访问。

预渲染

默认情况下,Next.js 将 预渲染 每个 page(页面)。这意味着 Next.js 会预先为每个页面生成 HTML 文件,而不是由客户端 JavaScript 来完成。预渲染可以带来更好的性能和 SEO 效果。

每个生成的 HTML 文件都与该页面所需的最少 JavaScript 代码相关联。当浏览器加载一个 page(页面)时,其 JavaScript 代码将运行并使页面完全具有交互性。
注意:这里面的预渲染其实就是服务端渲染,或者是指非客户端渲染。不是预先生成HTML(SSG)的意思。

两种形式的预渲染

Next.js 具有两种形式的预渲染: 静态生成(Static Generation) 和 服务器端渲染(Server-side Rendering)。这两种方式的不同之处在于为 page(页面)生成 HTML 页面的 时机 。

静态生成 (SSG):HTML 在 构建时 生成,并在每次页面请求(request)时重用。
服务器端渲染(SSR):在 每次页面请求(request)时 重新生成 HTML。
在这里插入图片描述

三个和预渲染有关的重要方法:

getStaticProps (Static Generation): Fetch data at build time.
getStaticPaths (Static Generation): Specify dynamic routes to pre-render pages based on data
getServerSideProps (Server-side Rendering): Fetch data on each request

getStaticProps

只要Pages中的文件有export getStaticProps,就认为是SSG

// getStaticProps
// 静态生成,只在打包构建时运行一次
import { GetStaticProps } from 'next'
export const getStaticProps: GetStaticProps = ({params}) => {
  // params参数是来自于getStaticPaths函数的返回结果
  ...
  return {
    props: {...},  // 只能返回这种格式的数据
    revalidate: sec // 每sec秒生成一次,
    nouFound: false // 为true时404
  }
}
getStaticProps几个细节

编译时运行,在用户请求前。dev模式下,在请求时运行
只在服务端/Node.js运行
数据必须和用户无关,和URL参数无关
页面最终会被编译成静态html

SSG应用场景

尽可能使用 静态生成 (带有或不带数据),因为你的所有 page(页面)都可以只构建一次并托管到 CDN 上,这比让服务器根据每个页面请求来渲染页面快得多。

预渲染(SSG):有什么问题?

编译阶段生成HTML,数据变更了怎么办?
HTML和用户/URL参数有关怎么办?
在这里插入图片描述

动态路由的SSG的问题

Dynamic routes 可以匹配近乎是无上限的 pattern,而每一个 pattern 如果在 next build 都要对应到一个页面,这样会产生无上限的 HTML 页面吗?
解决方案:
使用 getStaticPaths 事先定义哪些页面需要产生 HTML 档案。
语法跟 getStaticProps 很像,定义一个async function getStaticPaths ,回传值包含两个 key,分别是 paths 与 fallback。

getStaticPaths

// getStaticPaths
// 静态生成,只在打包构建时运行一次
// 使用于动态路由组件内,根据返回结果生成x.html,需配合getStaticProps函数使用
import { GetStaticPaths } from 'next'
export const getStaticPaths: GetStaticPaths = () => {
  ...
  return {
    paths: [
      {params: {id: '1'}},
      {params: {id: '2'}},
      ...
    ],
    fallback: true or false or blocking
    //最后的数据结果只能返回这种类型的,返回的params会出现在getStaticProps函数的params参数中,
    /* fallback为true时,对于不在paths中的动态路由也可以渲染,如果为false,对于不在paths中的路由,直接输出404 */
  }
}
getStaticPaths使用要点:

编译时运行,在用户请求前
动态路由场景
理解fallback很重要

SSG不适用的处理方案

不适用,即数据变化很快。或者说不适合提前渲染。

1、将“静态生成”与 客户端渲染(CSR) 一起使用:你可以跳过页面某些部分的预渲染,然后使用客户端 JavaScript 来填充它们。

2、使用 服务器端渲染(SSR): Next.js 针对每个页面的请求(eg:/post/1.html)进行预渲染。即用户每次请求的时候,服务端动态生成HTML。

SSR:getServerSideProps

// getServerSideProps
// 服务端渲染,每次页面运行时都会运行一次
// 性能上低于静态生成,更推荐上面的
import { GetServerSideProps } from 'next'
export const getServerSideProps: GetServerSideProps = () => {
  // 使用与上面一致
  ...
  return {
    props: {...}
  }
}

SSR不会在构建时生成静态HTML页面,但会在请求时渲染好再发给服务端,性能没有SSG好,但应用场景更加灵活。

Nextjs编译

yarn build  
# or
npm run build

SSG/SSR 总结

在这里插入图片描述

API开发

在这里插入图片描述

路由跳转——Link组件跳转

import Link from 'next/link'
export default () => {
  <Link href="/about" > 
    {/* href={pathname:"/about/“, query: {key: value} */}
    <a>点击跳转</a> {/* href会自动添加到a标签上 */}
  </Link>

  <Link href="/about" as="/a" > 
    <a>点击跳转</a> {/* 起了个别名,能跳转,且显示跳转到 /a ,但是刷新会404 */}
  </Link>

  <Link href="/about" passHref>
    <img /> {/* 如果子标签没有href属性,需要在Link中添加强制属性 passHref */}
  </Link>

  {/* 还有其他属性:replace: 替换,无法返回;scroll={true/false} 是否跳转后到页面顶部;prefetch:预加载*/}

  {/* Link标签里面也可以放组件,但是必须是React.forwardRef创建的组件 */}
   const NewLink = React.forwardRef((props, ref) => {
    return <a href={props.href} ref={ref}>新标签</a>
  }) 
}

动态路由 &路由参数

<Link href="/file/[id]" as="/file/123"></Link>
<Link href="/file/[...id]" as="/file/123/456"></Link>

router.push('/file/[id]') // "/file/123"
router.push('/file/[...id]') // "/file/123/456"

/* 接收路由参数 */
// [id].tsx
import { useRouter } from 'next/router'
const A = () => {
  const router =  useRouter()
  console.log(router.query) // {id: ''}
  return <a>链接{router.query.id}</a>
}
export default A

// [...id].tsx
import { useRouter } from 'next/router'
const A = () => {
  const router =  useRouter()
  console.log(router.query) // {id: array[]}
  return <a>链接{router.query.id[0]}</a>
}
export default A

关于404页面与路由重定向

import { GetStaticProps } from 'next'

export const getStaticProps: GetStaticProps = () => {
  // 这里data自己设置一个合适的参数就行,return的是重定向操作
  if(!data){
    return {
      notFound: true, //为404页面,只能用true
      redirect: { // 重定向,分开使用
        destination: "/",
        permanent: false,
    }
    }
  }
}

读取文件

读取文件与node中操作差不多,但是在目录路径获取上有一点区别
注意!!!nextjs中无法使用 nodejs的__dirname,用以代替的是process.cwd()`,返回的是项目工程的根目录的绝对路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值