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
相关产品推荐
相关产品推荐

