【问题标题】:Nextjs getStaticProps not firedNextjs getStaticProps 未触发
【发布时间】:2020-11-02 16:48:15
【问题描述】:

我的 [slug].js 文件如下,有两个 nextjs 辅助函数。 getStaticPaths 和 getStaticProps 被导出。在我的例子中,它创建了路径posts/[slug]。添加了一个名为hello.json 的帖子文件。现在,当我导航到 localhost:3000/posts/hello 时,它会出错:

TypeError: Cannot read property 'fileRelativePath' of undefined。对于第 10 行。

看到jsonFile 未定义后,这才有意义。事实上,整个getStaticProps 永远不会被调用,那里的登录永远不会被记录。为什么会这样?

提前致谢。

import React from 'react';
import glob from 'glob';
import { usePlugin } from 'tinacms';
import { useJsonForm } from 'next-tinacms-json';

const Page = ({ jsonFile }) => {
    console.log(121212, jsonFile);

    // Create the tina form
    const [post, form] = useJsonForm(jsonFile);

    // Register it with the CMS
    usePlugin(form);

    return (
        <h1>
            {post.title}
        </h1>
    );
};

export default Page;

/**
 * By exporting the async function called getStaticProps from a page, Next.js
 * pre-renders this page at build time using the props returned by
 * getStaticProps.
 * The getStaticPaths function defines a list of paths that have
 * to be rendered to HTML at build time.
 */

export async function getStaticProps({ ...ctx }) {
    console.log(1212, ctx);
    const { slug } = ctx.params;
    const dynamicPath = `../../posts/${slug}.json`; // for eslint parsing error: "Cannot read property 'range' of null Occurred while linting"
    const content = await import(dynamicPath);

    console.log(121212, content);

    return {
        props: {
            jsonFile: {
                fileRelativePath: `/posts/${slug}.json`,
                data: content.default,
            },
        },
    };
}

export async function getStaticPaths() {
    //get all .json files in the posts dir
    const posts = glob.sync('posts/**/*.json');

    const paths = posts.map(file => ({
        params: {
            slug: `${file.replace('.json', '')}`,
        },
    }));

    return {
        paths,
        fallback: true,
    };
};

【问题讨论】:

  • 你试过export async function getStaticPaths 而不是export const getStaticPaths = async ()
  • 是的,这没有任何区别。 getStaticPaths 似乎完成了它的工作。将编辑答案以使两个功能一致

标签: javascript reactjs next.js


【解决方案1】:

经过更多的挖掘,我发现了这个问题,在此发布,希望能帮助未来的读者解决同样的问题。

罪魁祸首是这样的:

const dynamicPath = `../../posts/${slug}.json`; // for eslint parsing error: "Cannot read property 'range' of null Occurred while linting"
const content = await import(dynamicPath);

在动态导入中使用变量不起作用,只能使用字符串或模板文字。我使用了一个变量,因为 eslint 解析错误只能通过降级到早期版本的 eslint 来解决。这会导致 eslint 在此文件中对我不起作用,但是好的,至少调用了该函数。

这与在调用 getStaticProps 之前调用组件代码的观察相结合,使得 jsonFile 变量未定义,并且整个组件在到达 getStaticProps 之前出错。您可以看到以121212 开头的日志比1212 更早进入。终端日志:

121212 {
  fileRelativePath: 'posts/hello.json',
  data: { title: 'Not the actual data' }
}
1212 hello

这对我来说是反直觉的,因为我认为它会首先获取道具并立即将它们传递给组件,但遗憾的是,需要定义默认道具来解决这个问题。

新代码:

import React from 'react';
import glob from 'glob';
import { usePlugin } from 'tinacms';
import { useJsonForm } from 'next-tinacms-json';

const Page = ({ jsonFile }) => {
    console.log(121212, jsonFile);

    // Get content and form for Tina
    const [content, form] = useJsonForm(jsonFile);

    // Register it with the CMS
    usePlugin(form);

    return (
        <h1>
            {content.title}
        </h1>
    );
};

Page.defaultProps = {
    jsonFile: {
        fileRelativePath: 'posts/hello.json',
        data: {
            title: 'Not the actual data',
        },
    },
};

export default Page;

/**
 * By exporting the async function called getStaticProps from a page, Next.js
 * pre-renders this page at build time using the props returned by
 * getStaticProps.
 */
export async function getStaticProps({ params: { slug } }) {
    console.log(1212, slug);

    // This line caused the issue
    // const dynamicPath = (`../../posts/${slug}.json`; // for eslint parsing error: "Cannot read property 'range' of null Occurred while linting"
    const content = await import(`../../posts/${slug}.json`);

    return {
        props: {
            jsonFile: {
                fileRelativePath: `posts/${slug}.json`,
                data: content.default,
            },
        },
    };
}

/**
 * The getStaticPaths function defines a list of paths that have
 * to be rendered to HTML at build time.
 */
export async function getStaticPaths() {
    //get all .json files in the posts dir
    const posts = glob.sync('posts/**/*.json');

    return {
        paths: posts.map(file => ({
            params: {
                slug: `${file.replace('.json', '')}`,
            },
        })),
        fallback: true,
    };
}

【讨论】:

    猜你喜欢
    • 2021-11-03
    • 2020-11-05
    • 2021-11-13
    • 2022-01-09
    • 2021-06-23
    • 1970-01-01
    • 2021-04-17
    • 2021-08-25
    相关资源
    最近更新 更多