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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:13:22