React中onClick函数未点击自动执行,点击无响应问题咨询
问题原因及修复方案
核心原因:按钮事件绑定错误
- React的点击事件属性是驼峰式的
onClick,你写成了小写的onclick,不符合React规范,导致点击按钮时无法触发事件。 - 你直接绑定了
openLong(),这会在组件每次渲染时立即执行函数,而非等待点击触发——这就是启动服务器后自动弹出多笔交易的根本原因。正确写法应该传递函数引用openLong(不带括号)。
其他加剧问题的细节
- 未用状态管理账户地址:
selectedAccount是普通变量,组件重渲染后会丢失值,应该用useState存储。 - 账户地址硬编码:交易里的
from写死了固定地址,应该用获取到的用户钱包地址selectedAccount。 - 重复初始化Web3和合约:
loadContract函数每次调用都会重新创建Web3实例和合约对象,多余的await会造成不必要的异步等待。 - 账户请求逻辑无限制:每次组件渲染都会执行
eth_requestAccounts,应该放到useEffect里只执行一次。
修复后的代码示例
import React, { useState, useEffect } from 'react'; import Web3 from 'web3'; import Contract from 'web3-eth-contract'; export default function KwentaOptimism() { const [provider, setProvider] = useState(window.ethereum); const [selectedAccount, setSelectedAccount] = useState(''); const [chainlinkFutureContract, setChainlinkFutureContract] = useState(null); // 初始化钱包和合约,仅执行一次 useEffect(() => { if (!provider) return; // 请求授权账户 provider.request({ method: 'eth_requestAccounts' }).then((accounts) => { setSelectedAccount(accounts[0]); console.log(`Selected account is ${accounts[0]}`); }); // 初始化Web3和合约 const web3 = new Web3(provider); Contract.setProvider(web3); const contract = new Contract( [{ constant: false, inputs: [{ internalType: 'int256', name: 'marginDelta', type: 'int256' }], name: 'transferMargin', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function', }], '0x1e28378F64bC04E872a9D01Eb261926717346F98' ); setChainlinkFutureContract(contract); }, [provider]); async function openLong() { if (!chainlinkFutureContract || !selectedAccount) return; try { await chainlinkFutureContract.methods .transferMargin('100000000000000000000') .send({ from: selectedAccount }); console.log('交易发送成功'); } catch (err) { console.error('交易失败:', err); } } return ( <div> <br /> <button onClick={openLong}>Chainlink Long</button> </div> ); }
内容的提问来源于stack exchange,提问作者blossom
相关产品推荐
相关产品推荐

