Next.js中getStaticProps传数据到React组件时出现undefined读取错误
问题:React组件无法访问getStaticProps传递的数据
我正在用Node.js、React和GraphQL搭建博客,对这些技术(包括JavaScript/TypeScript)都不熟悉,目前卡在文章数据展示环节:在getStaticProps函数里能正常读取GraphQL响应的数据,但把数据传给React组件后,无法访问数据,报错信息为TypeError: Cannot read properties of undefined (reading 'articles')。
以下是我的代码:
import {GetStaticProps} from "next"; import {serverSideTranslations} from "next-i18next/serverSideTranslations"; import {ssrGetBlog} from "../../generated/page"; // @ts-ignore implicitly has any type export default function Index(data) { console.log(data.attributes) //TypeError: Cannot read properties of undefined (reading 'articles') // 但在getStaticProps里这段代码能正常运行! return ( <div className="relative bg-gray-50 px-4 pt-16 pb-20 sm:px-6 lg:px-8 lg:pt-24 lg:pb-28"> <div className="absolute inset-0"> <div className="h-1/3 bg-white sm:h-2/3"/> </div> <div className="relative mx-auto max-w-7xl"> <div className="text-center"> <h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"> {data.blogHeading} </h2> <p className="mx-auto mt-3 max-w-2xl text-xl text-gray-500 sm:mt-4"> {data.blogDescription} </p> </div> <div className="mx-auto mt-12 grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3"> {data.attributes.articles.data.map((article) => ( <div key={article.attributes.title} className="flex flex-col overflow-hidden rounded-lg shadow-lg" > <div className="flex-shrink-0"> <img className="h-48 w-full object-cover" src={article.attributes.articleImg.data.attributes.url} alt="" /> </div> <div className="flex flex-1 flex-col justify-between bg-white p-6"> <div className="flex-1"> <p className="text-sm font-medium text-indigo-600"> <a href="not implemented: article.attributes.articleCategory.data.attributes.slug" className="hover:underline"> {"none existent: article.attributes.articleCategory.data.attributes.categoryName"} </a> </p> <a href={article.attributes.slug} className="mt-2 block"> <p className="text-xl font-semibold text-gray-900"> {article.attributes.title} </p> <p className="mt-3 text-base text-gray-500"> {article.attributes.shortDescription} </p> </a> </div> <div className="mt-6 flex items-center"> <div className="flex-shrink-0"> <a href="not implemented: article.attributes.author.href"> <span className="sr-only">{"not implemented: article.author.authorName"}</span> <img className="h-10 w-10 rounded-full" src="not implemented: article.attributes.author.authorImg" alt="" /> </a> </div> <div className="ml-3"> <p className="text-sm font-medium text-gray-900"> <a href="not implemented: article.attributes.author.authorUrl" className="hover:underline"> {"not implemented: article.attributes.author.name"} </a> </p> <div className="flex space-x-1 text-sm text-gray-500"> <time dateTime={article.attributes.publishedOn}>{article.attributes.publishedOn}</time> <span aria-hidden="true">·</span> <span>{"not implemented: article.attributes.readingTime"} read</span> </div> </div> </div> </div> </div> ))} </div> </div> </div> ); } export const getStaticProps: GetStaticProps = async (context) => { const {locale} = context; // @ts-ignore const blogQuery = await ssrGetBlog.getServerPage({}, context); const data = blogQuery.props.data?.blog?.data; //props.data?.blog?.data?.attributes; //console.log(data); // 正常输出 //console.log(data.attributes.articles.data[0]); // 正常输出 return { props: { data, ...(await serverSideTranslations(locale || "", ["common"])), }, }; };
解决方案
1. 修正组件接收props的方式
Next.js页面组件接收的是一个包含所有props的对象,不是直接的data参数。你当前的写法把整个props对象赋值给了data变量,导致data.attributes实际是在访问props.attributes,但props里只有data这个属性,所以会报错。
修改组件定义,解构props取出data:
// @ts-ignore implicitly has any type export default function Index({ data }) { console.log(data.attributes) // 现在能正确访问数据 // ... 其余代码保持不变 }
2. 添加空值保护(可选但推荐)
为了避免数据加载失败或返回undefined时再次报错,建议在访问嵌套属性时使用可选链操作符?.,同时给列表渲染添加空状态:
// 替换原有的map渲染代码 {data?.attributes?.articles?.data?.map((article) => ( // 文章卡片代码 )) || <p className="text-center col-span-3">暂无文章</p>}
内容的提问来源于stack exchange,提问作者Thomas Lehmann
相关产品推荐
相关产品推荐

