关于前端:一起来学-nextjs-getStaticPropsgetStaticPaths-篇

3次阅读

共计 3429 个字符,预计需要花费 9 分钟才能阅读完成。

之前讲过 next.js 中的 getServerSideProps,明天来讲一讲另一个很相似的 APIgetStaticProps,以及和 getStaticProps 严密相干的 getStaticPaths

getStaticProps 次要用于构建时落地一些静态数据,但不同于 getServerSidePropsgetStaticProps 默认状况下只会在构建时执行一次,之后的每次申请都会应用构建时的数据。在 ISRSSG 等场景下还有不同的体现。

getStaticPaths 则用于配合 getServerSideProps 实现动静路由的构建,next.js 会在构建时依据 getStaticPaths 的返回值来生成对应的动态页面。

应用

先看下 getStaticProps 如何应用,其实和 getServerSideProps 用法差不多:

export default function GetStaticProps({content}: {content: string}) {
    return (
        <div>
            <header>getStaticProps</header>
            <main>{content}</main>
        </div>
    );
}

export const getStaticProps = async () => {
    const content = 'Hello World';
    console.log('call getStaticProps');

    return {
        props: {content}
    };
};

只须要在 page 中导出 getStaticProps 函数,而后在函数中返回 props 即可。在 page 渲染组件中就能够间接通过 props 即可取得数据。

调用机会

再来看下 getStaticProps 的调用机会,这里和 getServerSideProps 存在很大差别:

  • 当执行 next build
  • getStaticPaths 返回 fallback 不为 false
  • 当应用了 revalidate

下面给出的例子是 getStaticProps 最简略的一个例子,只有在执行 next build 时才会调用 getStaticProps,之后的每次申请都会应用构建时的数据。

构建时 next.js 会将其构建为 html,并且还会构建一份 json 文件,存储 getStaticProps 的返回值,在拜访时首次进入页面为该页面时会间接应用 html 内容,而非首次进入则会去申请该 json 文件获取数据进行渲染。

json 文件中的数据如下:

{"pageProps": { "content": "Hello World"}, "__N_SSG": true }

能够看到和之前讲到的 getServerSideProps 的返回值是基本一致的,只是将 __N_SSP 参数变更为 __N_SSG,用以辨别两个数据的类型。

开发时的 getStaticProps

须要留神的是,在开发时也就是 next dev 时,getStaticProps 会在每次页面拜访时被申请,也就是和 getServerSideProps 行为基本一致,刚上手时很容易对这里感到困惑。

应用 getStaticPaths

getStaticPaths 次要用于动静路由中的动态页面构建,简略说就是将一个动静路由通过 getStaticPaths 转换为多个动态页面。

上面看下一个简略的例子:

pages/get-static-paths/[id].tsx

function GetStaticPaths({post}: {post: string}) {
    return (
        <div>
            <h1>Post: {post}</h1>
        </div>
    );
}

export async function getStaticPaths() {const paths = new Array(10).fill(0).map((_, i) => ({params: { id: i + 1 + ''}
    }));

    console.log('paths', paths);

    return {paths, fallback: true};
}

export async function getStaticProps({params}: {params: { id: string} }) {console.log('params', params);

    return {props: { post: `post ${params.id}` } };
}

export default GetStaticPaths;

此处是一个简略的动静路由,通过 getStaticPaths 咱们能够定义该动静路由的匹配的路由值,通过 paths[number] 中的 params 参数和动静路由中的参数进行匹配。以下是 next.js 将其转换为动态页面的步骤中 getStaticPathsgetStaticProps 相干的局部。

  1. 调用 next build 命令,next.js 会进行页面数据的收集,检测到动静路由时会尝试调用 getStaticPaths 并获取其返回值。
  2. 将返回值中的 paths 进行遍历,顺次取出和动静路由进行匹配,匹配后进行动态页面的生成步骤。
  3. path 中的 params 传入 getStaticProps 中,执行 getStaticProps 获取返回值。
  4. 通过返回值生成相应的 htmljson 文件

所以上述代码咱们在 next build 时将会生成 10 个动态页面 [1-10].html 和 10 个 JSON 文件 [1-10].json,生成的文件能够到 .next/server/pages/ 下查看。

fallback

此外下面的 DEMO 中能够看到 fallback 参数,fallback 其实有三个可选值:truefalseblocking,次要是用于管制 拜访动静路由时该地址未落地成动态页面时的解决

false 时根本就只有上述行为,当拜访不存在的页面时会返回 404 页面,比方下面拜访到 /get-static-paths/11 时会返回 404。

fallbacktrue 时会有一些不同,当拜访不存在的页面时不会返回 404,而是会返回动静路由页面,并且应用页面参数去申请 getStaticProps 数据,而后生成动态页面和 JSON 文件并将 JSON 文件返回动静渲染到页面中。而二次拜访该页面时因为曾经有了动态页面,就和其余已存在页面行为统一了。能够了解为一种 lazy build

fallbackblocking 时行为和 true 基本一致,但不同的是当拜访不存在的页面时会期待 getStaticProps 执行实现后再返回页面,不须要进行二次数据申请。所以首次拜访体现不统一,一个为异步一个为同步。

留神点

这里还有一个比拟须要关注的问题是 getStaticPaths 中的 params 中的 参数须要为字符串,否则将会导致无奈匹配,猜想为 next.js 中进行了类型判断或 map 操作,这个在后续源码剖析中细看。

此外和 getStaticProps 一样,在开发环境下 getStaticPaths 也会在每次拜访时被调用。

和 getServerSideProps

须要留神 getStaticPropsgetServerSideProps 无奈混用,在 next.js 的定位中,getStaticProps 次要用于 SSG 场景,而 getServerSideProps 次要用于 SSR 场景,在同一页面中应用时将会提醒:You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps

当然,集体感觉从设计上进行混用也没啥问题,getStaticProps 落地静态数据、getServerSideProps 落地动态数据,而后动静笼罩动态即可,next.js 这么设计可能是为了遵循繁多职能准则。

总结

最初来聊一聊什么场景下咱们应该应用 getStaticProps,其实官网应用文档里有列出举荐的应用场景,我这边说下本人的想法:如果页面中的数据是通过公布行为来进行更新的,那么就能够应用 getStaticProps。当然,要留神数据的安全性等问题。如果遇到页面中既有动态数据又有静态数据,那还是老老实实应用 getServerSideProps 吧。

当然,有同学可能发现下面只讲了两种 getStaticProps 的场景,而 revalidate 的场景没讲到,因为 revalidateISR 相干,这个前面再说(下次肯定,逃~)。

正文完
 0