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

如何在JS模块中导出依赖异步请求的非异步常量供React项目使用

解决方案

首先明确:客户端侧异步请求不可能直接返回完全同步的非异步常量,但可以通过以下两种方案实现最小程度的代码改动,原有使用TOKEN_MINTS的组件几乎不需要重写。

方案1:顶层预加载 + React Context 共享(推荐,改动最小)

这个方案只需要修改常量文件和应用入口文件,原有业务组件基本无需调整。

步骤1:修改常量TS文件

保留原有映射逻辑,新增初始化函数和Context导出:

import { createContext, useContext } from 'react';
import { PublicKey } from '@solana/web3.js'; // 替换为你实际的PublicKey导入路径

// 复用原有类型定义
export type TokenMintType = Array<{
    address: PublicKey;
    name: string;
}>;

// 定义兜底默认值,防止加载过程中调用报错
let TOKEN_MINTS: TokenMintType = [];

// 异步初始化加载函数
export async function initTokenMints() {
    try {
        const res = await fetch('你的JSON接口地址', {
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
        });
        if (!res.ok) throw new Error('接口请求失败');
        const rawMints = await res.json();
        // 完全复用原有静态JSON的映射逻辑
        TOKEN_MINTS = rawMints.map((mint) => {
            return {
                address: new PublicKey(mint.address),
                name: mint.name,
            };
        });
        return TOKEN_MINTS;
    } catch (e) {
        console.error('TOKEN_MINTS加载失败', e);
        return TOKEN_MINTS;
    }
}

// 导出Context供组件实时获取最新值
const TokenMintsContext = createContext<TokenMintType>(TOKEN_MINTS);
export const TokenMintsProvider = TokenMintsContext.Provider;
export const useTokenMints = () => useContext(TokenMintsContext);
// 保留原有导出方式兼容老代码,加载完成前返回兜底值
export { TOKEN_MINTS };

步骤2:修改应用入口文件

在渲染根组件前先执行数据初始化,完成后再挂载应用:

import { initTokenMints, TokenMintsProvider, TOKEN_MINTS } from './你的常量文件路径';
import App from './App';

// 等待数据加载完成再渲染应用
initTokenMints().then(() => {
    ReactDOM.createRoot(document.getElementById('root')!).render(
        <TokenMintsProvider value={TOKEN_MINTS}>
            <App />
        </TokenMintsProvider>
    )
});

步骤3:组件侧适配(可选,仅需修改一行导入)

如果需要保证组件拿到的永远是加载完成的最新值,只需要把原有导入逻辑替换为hooks调用即可,组件内部使用逻辑完全不用改:

// 原有导入写法
// import { TOKEN_MINTS } from 'xx'
// 替换为
import { useTokenMints } from 'xx'

const YourComponent = () => {
    const TOKEN_MINTS = useTokenMints();
    // 后续原有逻辑完全复用
}

方案2:ES模块顶级await(无需修改组件代码,需适配构建配置)

如果你的项目使用ES模块规范,且构建工具(Webpack5+/Vite/Rollup)和目标浏览器支持顶级await特性,可以直接修改常量文件如下,原有组件的导入和使用逻辑完全不用调整:

import { PublicKey } from '@solana/web3.js';

// 顶级await会等待请求完成后再导出模块内容
const rawMints = await fetch('你的JSON接口地址', {
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
}).then(res => {
    if (res.ok) return res.json();
    // 请求失败返回兜底空数组
    return [];
});

// 原有导出逻辑完全复用
export const TOKEN_MINTS: Array<{
    address: PublicKey;
    name: string;
}> = rawMints.map((mint) => {
    return {
        address: new PublicKey(mint.address),
        name: mint.name,
    };
});

注意:该方案会阻塞模块加载直到请求完成,请求失败会导致模块加载异常,需要提前做好降级处理,同时确认你的构建配置开启了顶级await支持。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:36:02