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

在React组件for循环中使用async/await报错,如何解决?

解决React组件中"Objects are not valid as a React child (found: [object Promise])"错误

问题原因

  • 你将组件定义为async function,React组件不能是异步函数——异步函数返回的是Promise,而React无法把Promise作为子元素渲染。
  • 在组件渲染阶段直接执行await fetchIPFSJSON,会阻塞渲染流程,同时生成Promise对象触发错误。
  • 初始状态下data为undefined,直接执行for (const a in data)会引发额外运行时问题。

修正后的代码

import { useState, useEffect } from 'react';
// 请确保已导入Card、StackGrid等所需组件

export default function DetailsViewer() {
  const [data, setData] = useState(null);
  const [processedMetadata, setProcessedMetadata] = useState([]);
  const [loading, setLoading] = useState(true);

  // 从后端获取NFT基础数据
  useEffect(() => {
    const getNFTDetails = async () => {
      try {
        const response = await fetch("http://localhost:4000/getDetails");
        const posts = await response.json();
        setData(posts);
      } catch (err) {
        console.error('获取NFT详情失败:', err);
      } finally {
        setLoading(false);
      }
    };
    getNFTDetails();
  }, []);

  // 批量获取并处理IPFS元数据
  useEffect(() => {
    if (!data) return;

    const fetchMetadata = async () => {
      const metadataList = [];
      for (const item of data) {
        const meta = await fetchIPFSJSON(item.uri);
        if (meta.image) {
          meta.image = makeGatewayURL(meta.image);
        }
        // 合并原数据与处理后的元数据,方便渲染
        metadataList.push({ ...item, ...meta });
      }
      setProcessedMetadata(metadataList);
    };

    fetchMetadata();
  }, [data]);

  // 处理加载状态
  if (loading) {
    return <div>加载中...</div>;
  }

  // 处理空数据状态
  if (!processedMetadata.length) {
    return <div>暂无数据</div>;
  }

  return (
    <div style={{ maxWidth: 820, margin: "auto", marginTop: 32, paddingBottom: 256 }}>
      <StackGrid columnWidth={200} gutterWidth={16} gutterHeight={16}>
        {processedMetadata.map(item => (
          <Card
            style={{ width: 200 }}
            key={item.name}
            title={
              <div>
                {item.name}{" "}
                <a
                  target="_blank"
                  rel="noreferrer"
                  href={/* 可补充跳转链接,比如NFT的详情地址 */}
                >
                  {/* <LinkOutlined /> */}
                </a>
              </div>
            }
          >
            <img src={item.image} style={{ maxWidth: 130 }} alt={item.name} />
          </Card>
        ))}
      </StackGrid>
    </div>
  );
}

关键修改说明

  • 移除组件的async关键字,确保组件返回合法的JSX元素。
  • 拆分异步逻辑:用两个useEffect分别处理后端数据获取、IPFS元数据批量请求,避免渲染阶段阻塞。
  • 新增loading状态优化加载体验,避免data未就绪时的报错。
  • 用map替代for...in循环,更符合React数组渲染的规范,同时避免遍历对象原型链的问题。
  • 合并原数据与处理后的元数据,让渲染时的数据源更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:40:40