React新手开发问题:渲染NFT列表时出现[object Promise]错误,需用数组替代渲染集合
解决React组件中"Objects are not valid as a React child (found: [object Promise])"错误
嘿,我来帮你搞定这个问题!你遇到的报错核心原因很明确:React函数组件不能是async函数——因为async函数执行后会返回一个Promise对象,而React没办法直接渲染Promise,这就是你看到那个错误的根源。咱们一步步来修复:
1. 重构ChooseProductView组件:去掉async,用useEffect+useState处理异步请求
React函数组件的返回值必须是React元素、null或者片段,不能是Promise。所以我们需要把异步请求移到useEffect钩子中,并用useState来管理NFT数据和加载状态:
import Link from 'next/link'; import { useWeb3Context } from '../../context' import { Web3Button } from '../../components'; import axios from 'axios'; import React, { useEffect, useState } from 'react'; import NFTContainer from '@/components/NFTContainer'; const renderNotConnectedContainer = () => ( <Web3Button/> ); export const ChooseProductView = () => { // 去掉async关键字 const { address } = useWeb3Context(); const [nfts, setNfts] = useState([]); // 用state存NFT数组 const [isLoading, setIsLoading] = useState(false); // 加载状态 // 当address变化时,发起请求获取NFT useEffect(() => { if (!address) return; const fetchNFTs = async () => { setIsLoading(true); try { const response = await axios.get(`https://ethereum-api.rarible.org/v0.1/nft/items/byOwner?owner=${address}`); // Rarible API返回的数据里,NFT列表在response.data.items中 setNfts(response.data.items); } catch (error) { console.error("获取NFT失败:", error); setNfts([]); } finally { setIsLoading(false); } }; fetchNFTs(); }, [address]); // 依赖address,地址变化时重新请求 if(!address){ return renderNotConnectedContainer(); } // 处理加载状态 if (isLoading) { return <div className="flex items-center justify-center py-8">加载中...</div>; } return( <div className="flex items-center justify-center"> <div className="border-grey md:w-full rounded-xl border sm:max-w-xl md:max-w-2xl"> <div className="flex flex-row justify-between py-2 px-6"> <span className="md:text-md text-left text-sm font-light lg:text-lg"> Address </span> <span className="md:text-md truncate pl-4 text-right text-sm font-light lg:text-lg"> {address} </span> </div> <NFTContainer nfts={nfts}/> {/* 传入实际的NFT数组 */} </div> </div> ); };
2. 修复NFTContainer组件:确保遍历的是数组
原来的代码中你传入的是axios的整个响应对象(不是数组),现在我们已经传入了response.data.items数组,所以修改NFTContainer组件,确保正确遍历:
import React from "react"; import NFTCard from "./NFTCard"; // 如果用TypeScript,可以定义NFT类型,这里先简化 const NFTContainer = ({nfts}) => { // 如果nfts是空数组,显示提示 if (nfts.length === 0) { return <div className="py-8 text-center">未找到NFT</div>; } return( <div> {nfts.map((nft, index) => ( <NFTCard nft={nft} key={index}/> {/* 建议用nft的唯一ID当key,比index更稳定 */} ))} </div> ) } export default NFTContainer
关键注意点
- 永远不要把React组件定义为async函数:组件必须返回可渲染的React节点,而不是Promise。异步操作都要放在
useEffect或者自定义hooks里。 - 处理异步请求的状态:一定要加上加载、错误、空数据的状态,提升用户体验,也避免潜在的渲染错误。
- 正确处理API返回结构:Rarible的API返回的NFT列表在
data.items中,要确保你拿到的是正确的数组再去调用map方法。
内容的提问来源于stack exchange,提问作者rohit
相关产品推荐
相关产品推荐

