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

React类组件转函数组件时调用质押智能合约存款功能报错问询

报错直接原因

你在函数组件中没有通过current属性访问useRef返回的DOM引用,导致inputRef.value为undefined,调用toString方法时报错。


具体修复方案

  1. ref使用修正
    函数组件中通过useRef创建的引用,必须通过.current属性访问绑定的DOM元素,首先在组件顶部初始化ref:
import { useRef, useState } from 'react'

// 组件内部声明
const inputRef = useRef(null)
const [loading, setLoading] = useState(false)

取值时修改为:

amount = inputRef.current.value.toString() 

同时可以加非空判断避免DOM未挂载时的异常:

if (!inputRef.current?.value) return
  1. 合约调用逻辑补充
    你的合约变量(tether、chadsVault、account)需要确保已经完成初始化,调用前加非空判断避免空值异常,同时补全loading状态管理:
function stakeTokensVault(amount) {
  // 前置非空判断
  if (!tether || !chadsVault || !account?.[0]) return
  setLoading(true)
  tether.methods.approve(chadsVault._address, amount).send({from: account[0]}).on('transactionHash', (hash) => {
    chadsVault.methods.stake(amount).send({from: account[0]}).on('transactionHash', (hash) => {
      setLoading(false)
    })
  }) 
}
  1. 按钮交互优化
    给按钮添加loading状态下的禁用逻辑,防止重复提交:
<button 
  type='submit'
  disabled={loading}
  onClick={(event) => {
    event.preventDefault()
    if (!inputRef.current?.value) return
    let amount = inputRef.current.value.toString() 
    amount = window.web3.utils.toWei(amount, 'Ether')
    props.stakeTokensVault(amount)
  }}
  className='btn btn-primary btn-lg btn-block'
>
  {loading ? '处理中...' : 'DEPOSIT'}
</button>

额外注意事项

  • 如果stakeTokensVault是父组件传入子组件的方法,建议父组件用useCallback包裹该方法,避免闭包陷阱导致读取到旧的合约/账户变量。
  • 可以给input添加min="0"属性,避免用户输入负数的异常情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:39:03