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

React集成Web3调用mintToken报.then不是函数错误

问题描述

在集成ERC721智能合约与React前端时,调用合约方法触发运行时报错,此前因react-scripts版本问题降级到v5以下版本后出现该错误,怀疑两者存在关联。
控制台报错信息:

Uncaught TypeError: _Web3Client__WEBPACK_IMPORTED_MODULE_1__.mintToken.then is not a function

报错截图:
报错截图

问题根因

该报错和react-scripts版本降级无任何关联,全部为代码逻辑错误导致,共3处问题:

  • 核心报错原因:App.js中未执行mintToken函数,直接对导入的函数对象本身调用.then()方法。async函数只有被执行后才会返回Promise实例,直接引用函数对象不存在then方法,因此触发类型错误。
  • 合约调用参数不匹配:Solidity合约中定义的mint()方法无入参,铸币目标地址默认取交易发起者msg.sender,但前端调用时错误传入了selectedAccount作为参数,会导致合约调用失败。
  • 初始化逻辑隐患:Web3初始化逻辑中未等待用户完成钱包授权就继续执行后续代码,可能出现selectedAccount为空、合约实例初始化异常的问题;同时Web3实例化时遗漏new关键字,不符合官方初始化规范。
修复方案

1. 修正App.js逻辑

首先在组件加载时提前初始化Web3连接,其次调用mintToken时添加括号执行函数,拿到Promise实例后再处理回调:

import React, { useEffect, useState } from 'react';
import { init, mintToken } from './Web3Client';
function App() {
  const [minted, setMinted] = useState(false);

  // 组件挂载时提前初始化Web3连接
  useEffect(() => {
    init().catch(err => console.log('Web3初始化失败:', err));
  }, []);

  const mint = () => {
    // 加()执行mintToken函数,拿到返回的Promise
    mintToken()
      .then((tx) => {
        console.log('铸币交易成功:', tx);
        setMinted(true);
      })
      .catch((err) => {
        console.log('铸币失败:', err);
      });
  };
  return (
    <div className="App">
      {!minted ? (
        <button onClick={() => mint()}>Mint Token</button>
      ) : (
        <p>Token Minted successfully</p>
      )}
    </div>
  );
}

export default App;

2. 修正Web3Client.js逻辑

给钱包授权请求加await保证执行顺序,补全Web3实例化的new关键字,移除合约mint方法调用时多余的参数:

import Web3 from 'web3';
import NFTContract from './NFT.json';
let selectedAccount;
let nftContract;
let isInitialized = false;

export const init = async () => {
  let provider = window.ethereum;
  if (typeof provider !== 'undefined') {
    // 等待用户完成钱包授权,再获取地址
    const accounts = await provider
      .request({ method: 'eth_requestAccounts' })
      .catch((err) => {
        console.log('钱包授权失败:', err);
        return;
      });
    selectedAccount = accounts[0];
    console.log(`selected account is ${selectedAccount}`);

    window.ethereum.on('accountsChanged', function (accounts) {
      selectedAccount = accounts[0];
      console.log(`Selected account changed to ${selectedAccount}`);
    });
  }
  // 补全new关键字初始化Web3实例
  const web3 = new Web3(provider);
  const networkId = await web3.eth.net.getId();
  nftContract = new web3.eth.Contract(
    NFTContract.abi,
    NFTContract.networks[networkId].address
  );
  isInitialized = true;
};

export const mintToken = async () => {
  if (!isInitialized) {
    await init();
  }
  // 合约mint方法无入参,移除多余的地址传参
  return nftContract.methods
    .mint()
    .send({ from: selectedAccount });
};

3. 注意事项

  • 确保MetaMask当前选中的网络和NFT合约部署的网络一致,否则会读取不到合约部署地址触发新的报错。
  • 确保已在前端项目目录下正确导入部署后生成的NFT.json合约ABI文件,且文件内包含对应网络的合约地址配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:36:27