Next.js -获取数据

- 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**.   

​```
```
export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}
```
context 是一个包含以下key的对象:
- params - 为使用动态路由的页面存放路径参数(route)  例,`[id].js` 在params中为 `{id:...}`. 一般和`getStaticPaths`搭配使用。
- preview - 为`true`时,page时preview 模式,其他为undefined
- previewData - 存放由`setPreviewData`设置的preview data
- locale  - 正在使用的locale
- locales - 所有支持的
- defaultLocale - 配置 的默认locale

返回的对象里包括:
* props - 可由page 里的组件接收的 对象
* ravalidate - 默认为false,此时不会做revalidate, 页面会缓存直到下次build
* notFound - 布尔值,是否允许页面返回404 和页面
* redirect - 配置重定向到的内部和外部资源
```js
 return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
```

TypeScript 中用 `GetStaticProps` 
```ts
import { GetStaticProps } from 'next'

export const getStaticProps: GetStaticProps = async (context) => {
  // ...
}
```

Next.js 默认静态生成的时间为60s
```js
// next.config.js
module.exports = {
  // time in seconds of no pages generating during static
  // generation before timing out
  staticPageGenerationTimeout: 90,
}
```

增量静态再生
Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**


```jsx
function Blog({ posts }) {
  return (
   


          {posts.map((post) => (
           
  • {post.title}

  •       ))}
       

  )
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: blocking } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: 'blocking' }
}

export default Blog
```

### 使用process.cwd() 直接读取文件
``__dirname` 在next.js 中不可用

```jsx
import { promises as fs } from 'fs'
import path from 'path'

// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
  return (
   


          {posts.map((post) => (
           

  •          

    {post.filename}


             

    {post.content}


           

  •       ))}
       

  )
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries. See the "Technical details" section.
export async function getStaticProps() {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)

  const posts = filenames.map(async (filename) => {
    const filePath = path.join(postsDirectory, filename)
    const fileContents = await fs.readFile(filePath, 'utf8')

    // Generally you would parse/transform the contents
    // For example you can transform markdown to HTML here

    return {
      filename,
      content: fileContents,
    }
  })
  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts: await Promise.all(posts),
    },
  }
}

export default Blog
```
 `getStaticProps` 只在build 时候运行一次,它并不能接收请求中的数据,比如查询参数,http headers。
只在sever 上运行

### `getStaticPaths`
```jsx
export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } } // See the "paths" section below
    ],
    fallback: true, false, or 'blocking' // See the "fallback" section below
  };
}
```
* paths -  检测哪一个path需要被预加载
`pages/posts/[id].js`
```js
return {
  paths: [
    { params: { id: '1' } },
    { params: { id: '2' } }
  ],
  fallback: ...
}
```

在build 时候会生成posts/1  和posts/2  使用`pages/posts/[id].js`.
#### fallback:false
不会返回任何路径,返回到404 页面。
#### fallback:true
getStaticProps 的行为会改变
* getStaticPaths 返回的路径会由getStaticProps 挂载到html
* build 时候没有自动生成的path 不会产生404 page。Next.js 会提供一个页面的fallback 版本。
  在这个Fallback 的页面中:props 是空的;查看这个fallback 是否正被挂载: `router.isFallback` will be `true`.

* 适用于有大量页面需要挂载

#### fallback: blocking
由 getStaticPaths 返回的新路径会等待html的生成

你可能感兴趣的:(javascript,前端,开发语言)