#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,
};
}