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

ReactJS TypeError:无法读取undefined的'raw'属性问题求助

问题:无法渲染富文本文章内容(body字段)

问题背景

从API获取文章数据后,控制台能看到完整数据,但页面渲染body(包含文本、图片、链接)和author等嵌套对象时出现报错,仅标题和日期可正常展示。

API返回的数据结构

{
  _createdAt: '2022-07-12T20:34:38Z',
  _id: 'bd2c8b42-dafc-4790-a2b4-58f26eaffc61',
  _rev: '7YXCB5lEK7kKTPSVqfqJAU',
  _type: 'post',
  _updatedAt: '2022-08-04T00:04:03Z',
  author: { _ref: 'a0ede624-53aa-47c8-8b46-0cc26fdccdb2', _type: 'reference' },
  body: [
    {
      _key: '19eb74b79eea',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '72c060bc0b85',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    { _key: '5ed0ee0d220b', _type: 'image', asset: [Object] },
    {
      _key: 'c4a2b577f8ca',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'ed759595ca4d',
      _type: 'block',
      children: [Array],
      level: 1,
      listItem: 'bullet',
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '9a9039e54e61',
      _type: 'block',
      children: [Array],
      level: 1,
      listItem: 'bullet',
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '3abb66409433',
      _type: 'block',
      children: [Array],
      level: 1,
      listItem: 'bullet',
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'e75487026e41',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '9e1d2e4a7bb8',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'fbe3a225084c',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'd00b4b88aad2',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '4e58b30c2ebb',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'ca9bdd4a4350',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    }
  ],
  categories: [
    {
      _key: '9cf008956dfe',
      _ref: 'f1f6d065-6720-4f3a-b462-f5c1e86829d4',
      _type: 'reference'
    }
  ],
  excerpt: 'some excerpts',
  featuredImage: [ { _key: '823231ffcf7b', _type: 'image', asset: [Object] } ],
  featuredPost: true,
  slug: { _type: 'slug', current: 'post-1' },
  title: 'Post Title'
}

当前React组件代码片段

const PostDetail = ({ post }) => {
  const getContentFragment = (index, text, obj, type) => {
    let modifiedText = text;

    if (obj) {
      if (obj.bold) {
        modifiedText = (<b key={index}>{text}</b>);
      }

      if (obj.italic) {
        modifiedText = (<em key={index}>{text}</em>);
      }

      if (obj.underline) {
        modifiedText = (<u key={index}>{text}</u>);
      }
    }
  };

  // 报错的渲染代码
  // {post.body.raw.children.map((typeObj, index) => {
  //   const children = typeObj.children.map((item, itemindex) => 
  //       getContentFragment(itemindex, item.text, item));
  //            return getContentFragment(index, children, typeObj, typeObj.type);
  //       })}
};

报错信息

TypeError: Cannot read property 'raw' of undefined

问题修复方案

1. 修正body字段的访问方式

API返回的body是直接的数组,不存在raw属性,原代码中post.body.raw是错误的,应直接遍历post.body数组。

2. 给getContentFragment添加返回值

原函数仅定义了modifiedText但未返回,导致React无法渲染有效内容,需在函数末尾添加return modifiedText;。

3. 处理不同类型的内容块

body数组包含block(文本/列表)和image(图片)等类型,需分类型处理:

  • 文本块:遍历其children处理加粗、斜体等标记;
  • 列表项:根据listItem属性渲染<li>标签;
  • 图片块:提取asset中的图片URL渲染<img>标签。

4. 处理author引用

author是引用类型,需确保API请求时已扩展获取完整的author数据(如姓名等),否则无法直接渲染。

修复后的完整组件代码

const PostDetail = ({ post }) => {
  const getContentFragment = (index, text, obj) => {
    let modifiedText = text;

    if (obj) {
      if (obj.bold) {
        modifiedText = <b key={index}>{text}</b>;
      }
      if (obj.italic) {
        modifiedText = <em key={index}>{text}</em>;
      }
      if (obj.underline) {
        modifiedText = <u key={index}>{text}</u>;
      }
    }
    // 返回处理后的文本节点
    return modifiedText;
  };

  const renderContentBlock = (block) => {
    switch (block._type) {
      case 'block':
        const textChildren = block.children.map((item, idx) => 
          getContentFragment(idx, item.text, item)
        );
        // 处理无序列表项
        if (block.listItem === 'bullet') {
          return <li key={block._key}>{textChildren}</li>;
        }
        // 处理普通段落
        return <p key={block._key}>{textChildren}</p>;
      case 'image':
        // 假设asset中包含url字段,若为Sanity需拼接CDN地址(如`https://cdn.sanity.io/images/.../${block.asset._ref}-${block.asset._id}.jpg`)
        const imageUrl = block.asset.url;
        return <img key={block._key} src={imageUrl} alt="文章内容图片" className="post-image" />;
      default:
        return null;
    }
  };

  return (
    <div className="post-detail-container">
      <h1 className="post-title">{post.title}</h1>
      <p className="post-date">发布于: {new Date(post._createdAt).toLocaleDateString('zh-CN')}</p>
      {/* 渲染文章主体内容 */}
      <div className="post-body">
        {post.body.map(block => renderContentBlock(block))}
      </div>
      {/* 渲染作者信息(需确保API已返回完整author数据) */}
      {post.author?.name && <p className="post-author">作者: {post.author.name}</p>}
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:06:21