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

React中OptionList无选项显示:一个下拉列表无法正常填充

下拉列表填充失败的问题排查与修复

问题概述

尝试通过两个异步函数填充两个下拉列表,frames列表正常显示,nonFramesComponent列表无内容。调用填充函数时,nonFramesArr[0]打印为undefined,展开数组时提示“This value was evaluated upon first expanding, it may have changed since then”。

核心原因

1. 异步请求未等待,函数提前返回空数组

getSmbFrameNfts和getNonFrameNfts函数中,fetch是异步操作,但代码没有等待所有fetch完成就返回了数组。for循环里的fetch会并行执行,但函数会直接返回初始的空数组frames,后续fetch完成后才会往数组里push数据,但此时调用者已经拿到了空数组,导致后续遍历数组时长度为0,无法生成选项。

2. 函数名不匹配(代码笔误)

填充函数populateListsWithNfts中调用了getFrames()和getNonFrames(),但实际定义的函数是getSmbFrameNfts和getNonFrameNfts,函数名不匹配会导致调用错误(如果无其他别名处理)。

3. 多余的await使用

document.getElementById("nonFramesComponent").innerHTML = await nonFrameStr;中,nonFrameStr是字符串而非Promise,await完全多余,属于错误用法。

修复方案

步骤1:等待所有异步请求完成

收集所有fetch的Promise,用Promise.all统一等待,确保返回数组时已填充数据。

步骤2:修正函数名匹配

确保填充函数调用的函数名和定义一致,比如将getFrames()改为getSmbFrameNfts(),getNonFrames()改为getNonFrameNfts()。

步骤3:移除多余的await

去掉对字符串变量的await调用。

修复后的完整代码示例

// 获取FRAME类型NFT的函数
const getSmbFrameNfts = async () => {
    const connection = await new Connection('mainnet-beta');
    const ownerPublicKey = walletAddress;
    const nftsmetadata = await Metadata.findDataByOwner(connection, ownerPublicKey);

    // 收集所有需要执行的fetch Promise
    const fetchPromises = [];
    for (const nft of nftsmetadata) {
        if (nft.data.symbol === 'FRAME') {
            fetchPromises.push(
                fetch(nft.data.uri).then(response => response.json())
            );
        }
    }
    // 等待所有fetch完成,返回结果数组
    return Promise.all(fetchPromises);
}

// 获取非FRAME类型NFT的函数
const getNonFrameNfts = async () => {
    const connection = await new Connection('mainnet-beta');
    const ownerPublicKey = walletAddress;
    const nftsmetadata = await Metadata.findDataByOwner(connection, ownerPublicKey);

    const fetchPromises = [];
    for (const nft of nftsmetadata) {
        if (nft.data.symbol !== 'FRAME') {
            fetchPromises.push(
                fetch(nft.data.uri).then(response => response.json())
            );
        }
    }
    return Promise.all(fetchPromises);
}

// 填充下拉列表的函数
const populateListsWithNfts = async () => {
    const frames = await getSmbFrameNfts();
    const nonFramesArr = await getNonFrameNfts();
    
    let frameStr = '';
    let nonFrameStr = '';

    for (const frame of frames) {
        frameStr += `<option value="${frame.name}">${frame.name}</option>`;
    }

    for (const nonFrame of nonFramesArr) {
        nonFrameStr += `<option value="${nonFrame.name}">${nonFrame.name}</option>`;
    }

    document.getElementById("nonFramesComponent").innerHTML = nonFrameStr;
    document.getElementById("frames").innerHTML = frameStr;
}

额外优化点

  • 使用for...of循环替代for...in或索引循环,代码更简洁可读
  • 修正选项标签格式:原自闭合标签<option value="..."/>部分浏览器无法正确渲染,改为包含显示文本的闭合标签<option value="...">显示文本</option>
  • 可复用Connection实例,避免重复创建提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:31:04