You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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">&middot;</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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:55:17