React----Next.js框架学习

一、Next.js是什么

Next.js是一款React的服务端渲染框架,用于构建SEO友好的SPA应用。Next.js具有同类框架中最佳的“开发人员体验”和许多内置功能:

  • 直观的、基于页面的路由系统,支持动态路由
  • 预渲染。支持在页面级的静态生成(SSG)和服务器端渲染(SSR)
  • 自动代码拆封,提升页面加载速度
  • 具有经过优化的预取功能的客户端路由
  • 内置CSS和Sass的支持,并支持任何CSS-in-JS库
  • 开发环境支持快速刷新
  • 利用Serverless Function及API路由构建API功能
  • 完全可扩展

浏览器访问网站时:输入一个网址,浏览器获取一个HTML页面,但此时页面没有数据,要使用fetch发送请求获取数据并使用useState设置state,state发生变化,此时render函数再一次渲染页面,因此此流程中有两个渲染周期。next.js则是利用第一个周期进行预渲染,可以减少首页白屏显示时间。

二、Next.js的基本特性

1、Page(页面)

每个page(页面)都是用其文件名作为路由(route)

例如:创建一个命名为''的文件并到处一个如下的React组件,则可以通过路径进行访问:pages/about.js''/about

function About() {
  return <div>About</div>
}

export default About

动态路由:

复杂的应用程序,使用预定义路径来定义路由并不足够,则使用向页面()添加括号以创建动态路由(也称为url slugs、pretty urls等)[param]

例如:pages/post/[pid].js

import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { pid } = router.query

  return <p>Post: {pid}</p>
}

export default Post

匹配的path参数将作为查询参数发送到页面,并与其他查询参数合并

 /post/1/post/abcpages/post/[pid].js

例如,路由将具有以下对象:`/post/abc```query`

{ "pid": "abc" }

`/post/abc?foo=bar``query`

{ "foo": "bar", "pid": "abc" }

预渲染:

next.js将预渲染每个page。会预先为每个页面生成HTML文件,而不是由客户端Javascript来完成。预渲染将带来更好的性能和SEO效果。

每个生成的HTML文件都与该页面所需的最少Javascrip代码相关联。当浏览器加载一个page(页面)时,其Javascript代码将运行并使页面完全具有交互性(水合) 

两种形式的预渲染:

静态生成和服务器端渲染,这两种方式的不同之处在于为page(页面)生成HTML页面的时机。

静态生成(推荐):HTML在构建时生成,并在每次页面请求(request)时重用。

服务器端渲染:在每次页面请求时重新生成HTML。

若一个页面使用了静态生成,在构建时将生成此页面对应的HTML文件,这意味着在生产环境中,运行时将生成该页面对应的HTML文件。此HTML文件将在每个页面请求时被重用,还可以被CDN缓存。

静态生成带有数据或不带有数据的页面:

1、生成不带数据的页面

此页面在预渲染时不需要获取任何外部数据,next.js只需要在构建时为每一个页面生成一个HTML文件即可。

function About() {
  return <div>About</div>
}

export default About

2、获取数据的静态生成

  • 页面内容取决于外部数据时可以使用函数 getStaticProps
  • 页面path(路径)取决于外部数据:使用函数 getStaticPaths、getStaticProps

页面内容取决于外部数据: 

例如:博客页面需要从CMS(内容管理系统)中获取博客文章列表,将预渲染时获取的数据作为参数传递给页面。

function Blog({ posts }) {
  // Render posts...
}

// 此函数在构建时被调用
export async function getStaticProps() {
  // 调用外部 API 获取博文列表
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 通过返回 { props: { posts } } 对象,Blog 组件
  // 在构建时将接收到 `posts` 参数
  return {
    props: {
      posts,
    },
  }
}

export default Blog

页面路径取决于外部数据:

假设:在向数据库添加了一篇博客文章,在构建时进行预渲染id: 1posts/1。之后又添加了第二篇文章,也希望对其进行预渲染id: 2posts/2。该函数在构建时被调用,并允许你指定要预渲染的路径。pages/posts/[id].jsexport(导出)getStaticPathsasync(异步)

// 此函数在构建时被调用
export async function getStaticPaths() {
  // 调用外部 API 获取博文列表
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 据博文列表生成所有需要预渲染的路径
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false }
}

同样在 中,你还需要export(导出) 以便可以获取 所对应的博客文章的数据并进行预渲染:pages/posts/[id].jsgetStaticPropsid

function Post({ post }) {
  // Render post...
}

export async function getStaticPaths() {
  // ...
}

// 在构建时也会被调用
export async function getStaticProps({ params }) {
  // params 包含此片博文的 `id` 信息。
  // 如果路由是 /posts/1,那么 params.id 就是 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // 通过 props 参数向页面传递博文的数据
  return { props: { post } }
}

export default Post

服务器端渲染:也称SSR或动态渲染

在每次页面请求时重新生成页面的HTML

例如,假设你的某个页面需要预渲染频繁更新的数据(从外部 API 获取)。 你就可以编写 获取该数据并将其传递给 ,如下所示:getServerSideProps  Page

function Page({ data }) {
  // Render data...
}

// This gets called on every request
export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

export default Page

2、数据提取

getStaticProps(Static Generation)

如果导出从页面调用的函数,Next.js将在构建时使用返回的props预呈现此页面。

export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

context对象包含:

  • params:包含使用动态路由的页面路由参数。
  • preview:是如果页面处于预览模式。
  • previewData:包含的预览数据集。
  • locale:包含活动区域设置。
  • locales:包含所有受支持的区域设置。
  • defaultLocale包含配置的默认区域设置。

getStaticProps应返回一个包含以下内容的对象:

props:带有页面组件将接收的props可选对象。

revalidate:以秒为单位的可选量,在此数量之后可以重新生成页面。

notFound:一个可选的布尔值,用于允许页面返回404状态和页面。

redirect:一个可选的重定向值,允许重定向到内部和外部资源。

export async function getStaticProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: { data }, // will be passed to the page component as props
  }
}

3、用户路由器

在组件内访问任何功能组件内的router对象,可以使用“useRouter”钩子(是一个React Hook,不能与类一起使用,可以使用withRouter或将类包装在一个函数组件中):

import { useRouter } from 'next/router'

function ActiveLink({ children, href }) {
  const router = useRouter()
  const style = {
    marginRight: 10,
    color: router.asPath === href ? 'red' : 'black',
  }

  const handleClick = (e) => {
    e.preventDefault()
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}

export default ActiveLink

router返回的对象的定义:‘useRouter’‘withRouter’

“isPreview":'boolean'应用程序当前是否处于预览模式

”isReady“:”boolean“路由器字段是否在客户端更新并准备好使用,只在’useEffect‘方法内部使用,而不是在服务器上进行有条件的渲染。

“pathname”:’string‘,当前路线。即页面的路径’/pages‘,配置 ’basePath‘或locale不包括在内。

“query”:‘object’,解析为对象的查询字符串。如果页面没有数据获取要求,则在预渲染期间它将是一个空对象。默认为{}

...

3.1路由器.push

router.push(url,as,options)

"url":  'Urlobject | String' 要导航到的URL

“as” :'Urlobject | String' 将在浏览器URL栏中显示的路径的可选装饰器。

“options” : 具有以下配置选项的可选对象:

  • ”scroll“ :可选布尔值,控制导航后滚动到页面顶部。默认为true
  • ”shallow“ :更新当前页面的路径而不重新运行”getStaticProps“,”getServerSideProps“或getInitialProps”。默认为‘false’
  • ”locale“ :可选字符串,表示新页面的语言环境

用法:

导航到”pages/about.js",这是一个预定义的路线:

import { useRouter } from 'next/router'
export default function page(){
    const router  = userouter()

    return (
        <button type="button" onClick={()=>router.push('/about')}>
            点击
        </button>
    )
}

 “pages/post/[pid].js”是一条动态路线:

    <button type="button" onClick={() => router.push('/post/abc')}>
      Click me
    </button>

(在next.js中导航到同一页面时,默认不会充值页面的状态,因为顶级Rreact组件是相同的,可以手动确保状态更新“useEffect”。

将用户重定向到,对身份验证“pages/login.js"后的页面很有用:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值