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

React Web3 NFT铸造报process未定义、钱包需双击连接问题

NFT铸造网站两个问题的原因及修复方案

问题1:连接钱包需要连续点击两次才能获取到钱包地址

产生原因

React 函数组件的setState是异步批处理机制:调用setWalletAddress、setContract时不会立刻修改当前函数闭包里的变量值,只会把更新任务加入队列,等当前同步代码执行完、组件重渲染后,新的state值才会生效。
你在调用set方法后立刻打印walletAddress和contract,拿到的永远是更新前的初始空值,第一次点击只是触发了state更新,等第二次点击触发函数执行时,闭包已经拿到了上一轮更新后的state,才会显示正确值,本质是代码写法问题,不是钱包连接功能真的需要触发两次。

修复代码

把connectWallet里的实例存在临时变量里使用,不要在当前上下文依赖刚set的state:

const connectWallet = async () => {
  if (typeof window.ethereum !== 'undefined') {
    const web3 = new Web3(window.ethereum);
    const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
    // 先把值存在临时变量
    const currentAddress = accounts[0];
    const contractInstance = new web3.eth.Contract(ABI, ADDRESS);
    // 再更新state
    setWalletAddress(currentAddress);
    setContract(contractInstance);
    // 用临时变量打印/后续操作,不要直接读state
    console.log(currentAddress)
    console.log(contractInstance)
  }
};

你的路由传props写法没有问题,state更新后组件重渲染会自动把最新的walletAddress和contract传给MintNow组件,不需要额外修改路由配置。

问题2:渲染MintNow页面抛出Uncaught ReferenceError: process is not defined错误

产生原因

这个是构建环境兼容问题,和你的业务逻辑无关:
你用的web3.js依赖部分Node.js原生全局对象,其中process是Node环境专属的变量,浏览器环境本身不存在。Vite、React 18+ 配套的webpack5默认不再自动注入Node.js模块的polyfill(兼容补丁),代码运行到调用process的位置就会抛出这个错误。

修复方案

根据你用的构建工具选对应方案:

  • 如果是Vite搭建的项目:
    1. 安装polyfill插件:
    npm install vite-plugin-node-polyfills -D
    
    1. 在项目根目录的vite.config.js里启用插件:
    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import { nodePolyfills } from 'vite-plugin-node-polyfills'
    
    export default defineConfig({
      plugins: [
        react(),
        nodePolyfills()
      ]
    })
    
  • 如果是新版create-react-app(webpack5)搭建的项目:
    在src/index.js最顶部手动加全局兜底定义即可:
    window.process = {
      env: { NODE_ENV: 'production' }
    }
    

额外优化建议

MintNow组件里的mint函数没有做初始化校验,用户没连钱包直接进入页面点Mint按钮会报contract不存在的错误,加个前置判断即可:

const MintNow = ({ walletAddress, contract }) => {
  const mint = async () => {
    if (!window.ethereum) return alert('请先安装MetaMask等钱包插件')
    if (!walletAddress || !contract) return alert('请先连接钱包后再铸造')
    const _mintAmount = Number(document.querySelector("[name=amount]").value);
    const mintRate = Number(await contract.methods.cost().call());
    const totalAmount = mintRate * _mintAmount;
    contract.methods.mint(walletAddress, _mintAmount).send({ from: walletAddress, value: String(totalAmount) })
  }
  return (
    <>
      <input type='number' name='amount' defaultValue='1' min='1' max='100' />
      <button onClick={mint}>Mint</button>
    </>
  );
}

export default MintNow;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:36:47