钱包内NFT存在但网站「我的资产」页面无法加载问题求助
问题:通过Web3Modal无法加载钱包中的NFT,页面显示空白
我正尝试通过Web3Modal获取钱包中当前持有的NFT,但钱包内确有NFT时,「我的资产」页面无法加载出这些NFT,仅显示空白。
补充说明
正常情况下,若钱包内无NFT,页面应显示“You don't own any of our assets...”,但实际无论钱包有无NFT,页面都只显示空白,全程无任何报错。我用两个钱包测试过——一个有NFT,一个无NFT,代码始终无法加载已存储的NFT。
相关代码
Solidity代码
(原提问中提供了对应代码截图,需结合合约逻辑排查)
React/JS代码
export default function MyAssets() { const [nfts1, setNfts1] = useState([]) const [loadingState, setLoadingState] = useState('not-loaded') const router = useRouter() useEffect(() => { loadNFTs1() }, []) async function loadNFTs1() { const web3Modal = new Web3Modal() const connection = await web3Modal.connect() const provider = new ethers.providers.Web3Provider(connection) const signer = provider.getSigner() const tokenContract = new ethers.Contract(nftaddress1, NFT1.abi, provider) const marketContract = new ethers.Contract(nftmarket1, Market1.abi, signer) const data = await marketContract.fetchMyNFTs() const items = await Promise.all(data.map(async i => { const tokenUri = await tokenContract.tokenURI(i.tokenId) const meta = await axios.get(tokenUri) let price = ethers.utils.formatUnits(i.price.toString(), 'ether') let item = { price, tokenId: i.tokenId.toNumber(), seller: i.seller, owner: i.owner, image: meta.data.image, name: meta.data.name, tag: meta.data.tag, description: meta.data.description, tokenUri } return item })) setNfts1(items) setLoadingState('loaded') } if (loadingState === 'loaded' && !nfts1.length) { return ( <div align="center" style={{ background: "#988558", height: "100%", minHeight: "72vh"}}> <center style={{ padding: "240px 0", textAlign: "center"}}> <h1 className="flex justify-center font-semibold" style={{ height: "100%", textAlign: "center"}}>You don't own any of our assets...</h1> </center> </div> ) } return ( <div align="center" style={{ background: "#988558", height: "100%", minHeight: "72vh"}}> <div className="flex justify-center"> <div className="p-4"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4"> { nfts1 && nfts1.map((nft, i) => ( <div key={i} className="border shadow rounded-xl overflow-hidden"> <img src={nft.image} style={{ height: '320px', width: '320px'}} className="rounded"/> <div className="p-1" style={{ background: "black"}}> <p style={{ height: '34px', 'textAlign': 'center', color: "white" }} className="text-2xl font-semibold">{nft.name}</p> </div> <div className="p-4 bg-black"> <p className="text-2xl font-bold text-white">Price - {nft.price} Matic</p> <button className="mt-4 w-full bg-pink-500 text-white font-bold py-2 px-12 rounded" onClick={() => listNFT(nft)}>List</button> <p className="text-1xl font text-white" style={{ float: "left", fontSize: "10px"}}>ID: {nft.tag}</p> </div> </div> )) } </div> </div> </div> </div> ) }
排查与解决方案
1. 检查fetchMyNFTs合约逻辑
- 确认Market合约的
fetchMyNFTs方法是否以msg.sender作为查询条件,返回当前调用者的NFT - 检查该方法是否仅返回已上架的NFT,如果钱包内的NFT未上架,会导致返回空数组
2. 添加错误捕获逻辑
当前代码无错误处理,任意步骤出错都会导致loadingState无法更新为loaded,页面一直空白。修改loadNFTs1:
async function loadNFTs1() { try { const web3Modal = new Web3Modal() const connection = await web3Modal.connect() const provider = new ethers.providers.Web3Provider(connection) const signer = provider.getSigner() const tokenContract = new ethers.Contract(nftaddress1, NFT1.abi, provider) const marketContract = new ethers.Contract(nftmarket1, Market1.abi, signer) const data = await marketContract.fetchMyNFTs() const items = await Promise.all(data.map(async i => { const tokenUri = await tokenContract.tokenURI(i.tokenId) const meta = await axios.get(tokenUri) let price = ethers.utils.formatUnits(i.price.toString(), 'ether') let item = { price, tokenId: i.tokenId.toNumber(), seller: i.seller, owner: i.owner, image: meta.data.image, name: meta.data.name, tag: meta.data.tag, description: meta.data.description, tokenUri } return item })) setNfts1(items) setLoadingState('loaded') } catch (err) { console.error('加载NFT失败:', err) setLoadingState('loaded') // 出错后仍更新状态,避免页面卡住 } }
3. 验证合约地址与ABI
- 确认
nftaddress1、nftmarket1是对应网络(测试网/主网)的正确地址 - 检查
NFT1.abi和Market1.abi与合约代码完全匹配,尤其是fetchMyNFTs、tokenURI的方法签名
4. 检查元数据访问
如果tokenURI返回IPFS链接,确认链接格式正确(比如是否带https://ipfs.io/ipfs/前缀),且能正常访问
5. 优化渲染逻辑
添加加载状态提示,避免初始阶段显示空白:
if (loadingState === 'not-loaded') { return ( <div align="center" style={{ background: "#988558", height: "100%", minHeight: "72vh", padding: "240px 0"}}> <h1 className="flex justify-center font-semibold">加载中...</h1> </div> ) } if (loadingState === 'loaded' && !nfts1.length) { return ( <div align="center" style={{ background: "#988558", height: "100%", minHeight: "72vh"}}> <center style={{ padding: "240px 0", textAlign: "center"}}> <h1 className="flex justify-center font-semibold">You don't own any of our assets...</h1> </center> </div> ) }
内容的提问来源于stack exchange,提问作者Wobbles
相关产品推荐
相关产品推荐

