Next.js中如何访问Sanity返回Post数组内嵌套的categories数组
问题分析
- 第一个错误是直接尝试渲染Sanity返回的category引用对象:Sanity的关联字段默认返回的是仅包含
_key、_ref、_type的引用对象,不是可直接渲染的字符串,React不允许把对象作为子元素渲染,所以会抛出对应错误。 - 第二个错误是
posts.categories.map的写法完全不符合数据结构:posts是Post对象组成的数组,没有顶层的categories属性,必须先遍历posts拿到单个Post对象,才能访问其下的categories数组。 - 第三个隐藏错误是解构赋值时给
categories设置的默认值为空字符串:categories本身是数组,默认值应该为空数组[],否则无分类数据时对字符串调用map方法也会抛出错误。
解决方法
步骤1:调整Sanity查询语句
你需要在查询时使用Sanity的解引用运算符->拉取分类关联的实际字段(比如分类名称title),参考GROQ查询写法:
*[_type == "post"] { _id, title, slug, mainImage, // 解引用categories关联,拉取分类的_id和title字段 categories[]-> { _id, title } }
调整后返回的categories数组内的元素就是包含实际分类信息的对象,不再是纯引用对象。
步骤2:修改渲染代码
调整解构默认值、渲染逻辑和key值:
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4"> {posts.map( ({ _id, title = "", slug = "", _createdAt = "", mainImage = "", categories = [], // 默认值改为空数组 }) => slug && ( <div className="shadow-lg rounded-lg bg-white pb-5" key={_id}> <div className="px-6 py-4 text-left"> <div className="flex flex-row mt-4 items-center"> {categories.length > 0 && ( <ul className="inline-flex my-3" style={{ listStyle: "none" }}> {categories.map((category) => ( {/* 用分类的唯一字段作为key */} <li key={category._id}> <span className="mx-2 items-center justify-center px-2 py-1 text-xs font-bold" > {/* 渲染分类的实际名称字段,不要直接渲染category对象 */} {category.title} </span> </li> ))} </ul> )} </div> </div> </div> ) )} </div>
内容的提问来源于stack exchange,提问作者theKid
相关产品推荐
相关产品推荐

