React类组件转函数组件时调用质押智能合约存款功能报错问询
报错直接原因
你在函数组件中没有通过current属性访问useRef返回的DOM引用,导致inputRef.value为undefined,调用toString方法时报错。
具体修复方案
- 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
- 合约调用逻辑补充
你的合约变量(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) }) }) }
- 按钮交互优化
给按钮添加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
相关产品推荐
相关产品推荐

