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

React中web3.js调用合约transferMargin函数时按钮自动触发问题

问题:页面刷新时自动调用合约函数,而非点击按钮触发

尝试通过React/Javascript(web3.js)和Metamask在Optimism Kovan网络调用Synthetix合约的transferMargin()函数,期望点击按钮时执行该合约函数,但页面启动或刷新时openLong()函数会自动调用,而非仅在点击“Chainlink Long”按钮时触发。以下是我的代码:

import react, { useState } from "react";
import  { Component } from 'react';
import Web3 from 'web3'


export default function KwentaOptimism()
{

let provider = window.ethereum;
let selectedAccount;


if (typeof provider !== 'undefined') {  
    provider
    .request({method: 'eth_requestAccounts' })
    .then((accounts) => {
    selectedAccount = accounts[0];
    console.log(`Selected account is ${selectedAccount}`);
    })
}

const web3 = new Web3(provider);

async function loadContract(){
    let address = "0x1e28378F64bC04E872a9D01Eb261926717346F98";
    let chainlinkFutureContractABI = [{"constant":false,"inputs":[{"internalType":"int256","name":"marginDelta","type":"int256"}],"name":"transferMargin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];

    var Contract = require('web3-eth-contract');
    var chainlinkFutureContract = new Contract(chainlinkFutureContractABI, address);

    return await chainlinkFutureContract;
}

async function openLong(){
    let linkContract = await loadContract();
    linkContract.methods.transferMargin("100000000000000000000").send({from: '0xce05626e35c053995d4988b75af85e2eb7251b3c'});
}

return(
    <div>
        <br/>
        <button onclick = {openLong()}>Chainlink Long</button>
    </div>
)
}

原因与解决方案

核心原因

问题出在按钮的事件绑定上:你写的是onclick = {openLong()},这里的openLong()会在组件渲染时立即执行(因为括号()是函数调用语法),而不是等待点击事件触发。另外React中的事件属性是驼峰命名,应该用onClick而非小写的onclick,否则可能无法正确绑定点击逻辑。

修复步骤

  1. 将按钮的onclick改为onClick,并去掉函数后的括号,传递函数引用而非直接调用:
    <button onClick={openLong}>Chainlink Long</button>
    
  2. 额外优化点:
    • loadContract函数里不需要await,因为new Contract是同步操作,直接返回实例即可
    • openLong函数中添加try/catch捕获调用异常,方便排查问题
    • 尽量使用用户授权的selectedAccount作为交易发起地址,而非硬编码地址

修改后的完整代码

import React, { useState } from "react";
import Web3 from 'web3'

export default function KwentaOptimism() {
  let provider = window.ethereum;
  let selectedAccount;

  if (typeof provider !== 'undefined') {  
    provider.request({method: 'eth_requestAccounts' })
      .then((accounts) => {
        selectedAccount = accounts[0];
        console.log(`Selected account is ${selectedAccount}`);
      })
      .catch(err => console.error('请求账户失败:', err));
  }

  const web3 = new Web3(provider);

  function loadContract(){
    const address = "0x1e28378F64bC04E872a9D01Eb261926717346F98";
    const chainlinkFutureContractABI = [{"constant":false,"inputs":[{"internalType":"int256","name":"marginDelta","type":"int256"}],"name":"transferMargin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];

    const Contract = require('web3-eth-contract');
    return new Contract(chainlinkFutureContractABI, address);
  }

  async function openLong(){
    try {
      const linkContract = loadContract();
      await linkContract.methods.transferMargin("100000000000000000000")
        .send({from: selectedAccount || '0xce05626e35c053995d4988b75af85e2eb7251b3c'});
      console.log('保证金转账成功');
    } catch (err) {
      console.error('保证金转账失败:', err);
    }
  }

  return(
    <div>
      <br/>
      <button onClick={openLong}>Chainlink Long</button>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:06:56