React项目中Sanity Schema嵌套数组映射图片报错求助
问题
在React项目中遍历Sanity的categories Schema里的features图片数组,使用嵌套map渲染图片时出现两个错误:
- 提示
src为不支持的ImageUrlBuilder类型,需转成字符串后使用 - 无法解析undefined的图片源
控制台打印数据正常,其他页面用相同逻辑渲染没问题,尝试过.url()方法仍未解决。
相关代码
Sanity Schema文件 categories.js
export default{ name: 'categories', title: 'Categories', type: 'document', fields: [ { name: 'category', title: 'Category (eg Clothing)', type: 'string', }, { name:'features', title: 'Features', type: 'array', of: [ { name:'featureimg', title: 'Feature Image', type:'image', options: { hotspot: true, }, }, ] }, ] }
React组件 product.js
import React, { useState, useEffect } from "react"; import { urlFor, client } from "../../client"; const Product = () => { const [categories, setCategories] = useState([]); useEffect(() => { const query1 = '*[_type == "categories"] | order(title asc)'; client.fetch(query1).then((data) => { setCategories(data); // console.log(categories[1].features.length); // console.log(urlFor(categories[1].features[1].featureimg)); }); }, []); return ( <div> <div className="app__work-filter"> {categories.map((item, index) => ( <div key={index}> <div> {item.category} <div> {item.features.map((feature, index) => ( <img src={urlFor(feature.featureimg)} alt=" " loading="lazy" /> ))} </div> </div> </div> ))} </div> </div> ); }; export default Product;
client.js文件
import { createClient } from '@sanity/client'; import imageUrlBuilder from '@sanity/image-url'; export const client = createClient({ projectId: process.env.REACT_APP_SANITY_PROJECT_ID, dataset: 'production', apiVersion: '2023-04-01', useCdn: true, token: process.env.REACT_APP_SANITY_TOKEN, }); const builder = imageUrlBuilder(client); export const urlFor = (source) => builder.image(source);
报错信息
Warning: The provided `src` attribute is an unsupported type ImageUrlBuilder. This value must be coerced to a string before using it here. Uncaught Error: Unable to resolve image URL from source (undefined) at urlForImage (urlForImage.ts:43:1) at ImageUrlBuilder.url (builder.ts:252:1) at ImageUrlBuilder.toString (builder.ts:257:1) at testStringCoercion (react-dom.development.js:259:
解决方法
1. 转换ImageUrlBuilder为字符串
urlFor()返回的是ImageUrlBuilder对象,不是直接可用的URL字符串,必须调用.url()或.toString()方法转换成字符串:
src={urlFor(feature.featureimg).url()}
2. 处理undefined的图片源
报错提示“无法解析undefined的图片源”,说明存在feature.featureimg为空的情况,需要添加判断:
- 方式一:渲染img前先检查图片是否存在
{item.features.map((feature, index) => ( feature.featureimg && ( <img key={index} src={urlFor(feature.featureimg).url()} alt={`${item.category} feature`} loading="lazy" /> ) ))}
- 方式二:给urlFor添加默认值,避免传入undefined
修改client.js中的urlFor:
export const urlFor = (source) => { return source ? builder.image(source) : builder.image('你的默认图片assetId'); };
3. 优化Sanity查询,确保图片数据完整
Sanity默认不会返回嵌套图片的完整asset数据,需要在查询中明确指定字段,避免数据缺失导致undefined:
修改product.js中的查询语句:
const query1 = '*[_type == "categories"] | order(title asc){category, features[]{featureimg{asset->}}}';
4. 补充稳定的key属性(可选但推荐)
嵌套map的每个元素都应该有唯一key,避免React警告,优先使用Sanity数组项自动生成的_key(比index更稳定):
<img key={feature._key || index} src={urlFor(feature.featureimg).url()} alt={`${item.category} feature`} loading="lazy" />
内容的提问来源于stack exchange,提问作者Yashwant
相关产品推荐
相关产品推荐

