React调用Thirdweb合约函数报错及区块链数据展示求助
问题解决:React+Thirdweb调用Solidity合约获取并展示用户数据
错误原因总结
- App.js中调用的
call()函数未被正确导入,refer.js内的call是组件内部私有函数,未对外暴露 - refer.js存在语法错误:重复导出了两个同名的
Component组件 useContractRead使用不当:未正确传递_userId参数,也未处理异步加载逻辑
修正后的代码实现
1. 修正refer.js:封装合约交互逻辑
将合约交互逻辑拆分为可复用的组件方法和自定义Hook,避免重复导出问题:
import { useContract, useContractWrite, useContractRead } from "@thirdweb-dev/react"; // 封装创建用户的方法 export function CreateUserComponent() { const { contract } = useContract("0xBB417720eBc8b76AdeAe2FF4670bbc650C3E791f"); const { mutateAsync: createUser, isLoading } = useContractWrite(contract, "createUser"); const callCreateUser = async () => { try { const data = await createUser([ "John0312", "John", "s", "8090890367", "03-11-2000", 20, "India", "M" ]); console.info("用户创建成功", data); return true; } catch (err) { console.error("用户创建失败", err); return false; } }; return { callCreateUser, isLoading }; } // 封装获取用户数据的自定义Hook export function useGetUser(userId) { const { contract } = useContract("0xBB417720eBc8b76AdeAe2FF4670bbc650C3E791f"); const { data: userData, isLoading: isLoadingUser } = useContractRead( contract, "getUser", userId ? [userId] : [] ); return { userData, isLoadingUser }; }
2. 修正App.js:导入逻辑并实现数据展示
导入refer.js中的封装函数,实现创建用户和展示用户数据的功能:
import React, { useState } from 'react'; import { CreateUserComponent, useGetUser } from './refer'; function App() { const { callCreateUser, isLoading } = CreateUserComponent(); const [targetUserId, setTargetUserId] = useState("John0312"); const { userData, isLoadingUser } = useGetUser(targetUserId); const handleClick = async (e) => { e.preventDefault(); const success = await callCreateUser(); if (success) { console.log("用户创建完成,可查看数据"); } }; return ( <div style={{ padding: "2rem" }}> <button onClick={handleClick} disabled={isLoading} > {isLoading ? "创建中..." : "创建测试用户"} </button> <div style={{ marginTop: "2rem" }}> <h3>用户数据展示</h3> {isLoadingUser ? ( <p>加载用户数据中...</p> ) : userData ? ( <div> <p>姓名: {userData[0]} {userData[1]}</p> <p>手机号: {userData[2]}</p> <p>出生日期: {userData[3]}</p> <p>年龄: {userData[4]}</p> <p>国籍: {userData[5]}</p> <p>性别: {userData[6]}</p> </div> ) : ( <p>未找到该用户数据</p> )} </div> </div> ); } export default App;
3. 必要配置补充
- 确保项目根组件(如index.js)已配置Thirdweb Provider,指定合约部署的区块链网络:
import { ThirdwebProvider } from "@thirdweb-dev/react"; import App from "./App"; ReactDOM.createRoot(document.getElementById('root')).render( <ThirdwebProvider activeChain="polygon"> {/* 替换为你的合约部署网络 */} <App /> </ThirdwebProvider> );
- 需确保用户已连接钱包(可添加
useMetamask组件实现钱包连接),否则无法执行合约写入操作 - 替换合约地址为你实际部署的合约地址,网络配置需与合约部署网络一致
内容的提问来源于stack exchange,提问作者Gowtham
相关产品推荐
相关产品推荐

