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

React从Contentful获取文章映射报错:TypeError: Cannot read property 'id' of undefined

解决Contentful数据映射时的TypeError问题

我来帮你搞定这个问题,你遇到的TypeError: Cannot read property 'id' of undefined其实是个很典型的新手小坑,咱们一步步拆解解决:

错误根源:状态被错误包装成二维数组

你在useEffect里更新状态的时候犯了个小失误:

setArticle([res.items]);

Contentful的getEntries()返回的res.items本身就是一个包含所有文章条目的数组了,你再用[]把它包裹起来,就变成了二维数组(结构大概是[[entry1, entry2, entry3]])。

当你调用article.map()的时候,遍历的是外层数组,第一个entry拿到的是整个res.items数组,而不是单个文章对象,自然没有sys.id属性,所以直接触发报错。

修复步骤

1. 修正状态更新逻辑

把状态更新代码改成直接赋值res.items,去掉多余的数组包裹,同时建议加上错误捕获方便排查问题:

useEffect(() => {
  client.getEntries()
    .then((res) => {
      setArticle(res.items); // 直接传入res.items即可
    })
    .catch(err => console.error('获取Contentful数据失败:', err))
}, [])

2. 正确处理图片地址

Contentful的媒体资产(比如你的featuredImage)不能直接取sys或者直接用entry.fields.featuredImage,需要访问fields.file.url才能拿到真实的图片链接,同时用可选链?.避免图片字段为空时再次报错:

<img src={entry.fields.featuredImage?.fields.file.url} alt={entry.fields.title || '文章封面'} />

3. 正确渲染富文本内容

你直接渲染entry.fields.body.data的话,页面会显示JSON字符串,Contentful提供了官方的富文本渲染工具,咱们用上它:
首先安装依赖:

npm install @contentful/rich-text-react-renderer

然后在组件中导入并使用:

import { documentToReactComponents } from '@contentful/rich-text-react-renderer';

// 渲染时替换成:
{documentToReactComponents(entry.fields.body)}

完整修正后的代码

import React, { useState, useEffect} from 'react'
import * as contentful from 'contentful';
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';

const BlogComponent = () => {
  const [article, setArticle] = useState([]);
  const client = contentful.createClient({
    space: 'xxxxxxxx' ,
    accessToken: 'xxxxxxxxxxxxxxxxxxxxxxxx'
  });

  useEffect(() => {
    client.getEntries()
      .then((res) => {
        setArticle(res.items);
      })
      .catch(err => console.error('获取Contentful数据失败:', err))
  }, [])

  const Articles = article.map((entry) => {
    return(
      <div className="entry" key={entry.sys.id}>
        <h1>{entry.fields.title}</h1>
        <img src={entry.fields.featuredImage?.fields.file.url} alt={entry.fields.title} />
        {documentToReactComponents(entry.fields.body)}
      </div>
    )
  })

  return (
    <div>
      {Articles}
    </div>
  )
}

export default BlogComponent

这样修改之后,应该就能正常渲染你的文章列表了。如果还有其他字段的问题,记得先console.log(entry)看看具体的数据结构,Contentful的返回数据层级比较多,一定要对应好路径~

内容的提问来源于stack exchange,提问作者Mazino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:52:30