Nextjs getStaticProps не запущен

#javascript #reactjs #next.js

#javascript #reactjs #next.js

Вопрос:

Мой [slug].js-файл, приведенный ниже, содержит две вспомогательные функции nextjs. Экспортируются getStaticPaths и getStaticProps. В моем случае он создает путь posts/[slug] . Добавлен один вызываемый post-файл 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,
    };
};
  

Комментарии:

1. вы пробовали export async function getStaticPaths вместо export const getStaticPaths = async ()

2. Да, это не имеет никакого значения. Похоже, getStaticPaths выполняет свою работу. Отредактирует ответ, чтобы сделать обе функции согласованными

Ответ №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,
    };
}