如何使用 NextJS 预渲染解决 "Cannot read property 'title' of undefined"?
How to solve "Cannot read property 'title' of undefined" using NextJS prerendering?
我正在为我的 Next.js 应用程序中的特定 post 预呈现此页面:
import Head from 'next/head';
import Link from 'next/link';
import client from '../../lib/apollo/client'
import POSTS_WITH_SLUGS from '../../lib/queries/allposts'
import POST from '../../lib/queries/post'
import styles from '../../styles/Home.module.css';
import blogStyles from '../../styles/Blog.module.css';
export default function Post({ postData }) {
const router = useRouter();
if (!router.isFallback && !postData?.slug) {
return <p>hmm... looks like an error</p>
}
const formatDate = date => {
const newDate = new Date(date);
return `${newDate.getDate()}/${
newDate.getMonth() + 1
}/${newDate.getFullYear()}`
};
return (
<div className={styles.container}>
<Head>
<title>{postData.title}</title>
<link rel='icon' href='/favicon.ico' />
</Head>
<main className={styles.main}>
{router.isFallback ? (
<h2>Loading...</h2>
) : (
<article className={blogStyles.article}>
<div className={blogStyles.postmeta}>
<h1 className={styles.title}>{postData.title}</h1>
<p>{formatDate(postData.date)}</p>
<img src={postData.featuredImage.node.sourceUrl} />
</div>
<div
className='post-content content'
dangerouslySetInnerHTML={{ __html: postData.content }}
/>
</article>
)}
<p>
<Link href={`/blog`}>
<a>Back</a>
</Link>
</p>
</main>
</div>
)
}
export async function getStaticPaths() {
// const allPosts = await getAllPostsWithSlug();
const { data } = await client.query({
query: POSTS_WITH_SLUGS
});
if (
data?.posts &&
data?.posts.edges !== null &&
data?.posts.edges.node !== null &&
data?.posts.edges.length > 0
) {
return {
paths: data?.posts.edges.map(({ node }) => `/blog/${node.slug}`) || [],
fallback: true
}
}
}
export async function getStaticProps({ params }) {
const { data } = await client.query({
query: POST,
variables: {
id: params.slug,
idType: 'SLUG'
}
});
return {
props: {
postData: data.post
}
};
}
在 npm run dev
上一切正常,但是当我 运行 npm run build
时出现此错误:
Error occurred prerendering page "/blog/[slug]". Read more: https://err.sh/next.js/prerender-error
TypeError: Cannot read property 'title' of undefined
我认为错误是由于 Next 中的 <Head>
组件造成的,我试图通过 {postData.title}
动态设置 <title>
。我从 getStaticProps()
.
获取数据作为道具
我不确定自己犯了什么错误,但我想知道是否必须在 /pages
目录之外创建 <Head>
组件。
让我解释一下 Next.js 在初始构建后请求任何其他 post 时将如何“回退”。有两个选项可供选择:blocking
和 true
.
fallback: blocking
(首选)——当向尚未生成的页面发出请求时,Next.js 将在第一个请求时服务器呈现该页面。未来的请求将从缓存中提供静态文件。
fallback: true
– 当向尚未生成的页面发出请求时,Next.js 将在第一个请求时立即提供具有加载状态的静态页面。数据加载完成后,页面将使用新数据重新呈现并缓存。未来的请求将从缓存中提供静态文件。
除非您想提供静态加载 shell,然后在客户端加载您的 post,否则我会将 true
更改为 blocking
。这将解决您的问题!
我正在为我的 Next.js 应用程序中的特定 post 预呈现此页面:
import Head from 'next/head';
import Link from 'next/link';
import client from '../../lib/apollo/client'
import POSTS_WITH_SLUGS from '../../lib/queries/allposts'
import POST from '../../lib/queries/post'
import styles from '../../styles/Home.module.css';
import blogStyles from '../../styles/Blog.module.css';
export default function Post({ postData }) {
const router = useRouter();
if (!router.isFallback && !postData?.slug) {
return <p>hmm... looks like an error</p>
}
const formatDate = date => {
const newDate = new Date(date);
return `${newDate.getDate()}/${
newDate.getMonth() + 1
}/${newDate.getFullYear()}`
};
return (
<div className={styles.container}>
<Head>
<title>{postData.title}</title>
<link rel='icon' href='/favicon.ico' />
</Head>
<main className={styles.main}>
{router.isFallback ? (
<h2>Loading...</h2>
) : (
<article className={blogStyles.article}>
<div className={blogStyles.postmeta}>
<h1 className={styles.title}>{postData.title}</h1>
<p>{formatDate(postData.date)}</p>
<img src={postData.featuredImage.node.sourceUrl} />
</div>
<div
className='post-content content'
dangerouslySetInnerHTML={{ __html: postData.content }}
/>
</article>
)}
<p>
<Link href={`/blog`}>
<a>Back</a>
</Link>
</p>
</main>
</div>
)
}
export async function getStaticPaths() {
// const allPosts = await getAllPostsWithSlug();
const { data } = await client.query({
query: POSTS_WITH_SLUGS
});
if (
data?.posts &&
data?.posts.edges !== null &&
data?.posts.edges.node !== null &&
data?.posts.edges.length > 0
) {
return {
paths: data?.posts.edges.map(({ node }) => `/blog/${node.slug}`) || [],
fallback: true
}
}
}
export async function getStaticProps({ params }) {
const { data } = await client.query({
query: POST,
variables: {
id: params.slug,
idType: 'SLUG'
}
});
return {
props: {
postData: data.post
}
};
}
在 npm run dev
上一切正常,但是当我 运行 npm run build
时出现此错误:
Error occurred prerendering page "/blog/[slug]". Read more: https://err.sh/next.js/prerender-error
TypeError: Cannot read property 'title' of undefined
我认为错误是由于 Next 中的 <Head>
组件造成的,我试图通过 {postData.title}
动态设置 <title>
。我从 getStaticProps()
.
我不确定自己犯了什么错误,但我想知道是否必须在 /pages
目录之外创建 <Head>
组件。
让我解释一下 Next.js 在初始构建后请求任何其他 post 时将如何“回退”。有两个选项可供选择:blocking
和 true
.
fallback: blocking
(首选)——当向尚未生成的页面发出请求时,Next.js 将在第一个请求时服务器呈现该页面。未来的请求将从缓存中提供静态文件。fallback: true
– 当向尚未生成的页面发出请求时,Next.js 将在第一个请求时立即提供具有加载状态的静态页面。数据加载完成后,页面将使用新数据重新呈现并缓存。未来的请求将从缓存中提供静态文件。
除非您想提供静态加载 shell,然后在客户端加载您的 post,否则我会将 true
更改为 blocking
。这将解决您的问题!