用途
Wagmi 为以太坊提供 React hooks。本技能用于确保在使用 Wagmi 构建 React 或 Next.js 应用时采用正确的模式,覆盖 Provider 配置、hooks 使用以及 React 相关的常见陷阱,适用于需要实现钱包连接、合约读取与写入等 EVM 交互的场景。
版本信息:Wagmi 3.x,要求 TypeScript 5.7.3+。
主要能力与核心 Hooks
useAccount
读取账户状态,例如 address、isConnected、isConnecting、chain。
useConnect / useDisconnect / useConnectors
处理钱包连接与断开。v3 中改用 useConnectors() hook 获取连接器,而非从 useConnect() 获取。
useReadContract(替代 useContractRead)
读取合约,返回 data、isLoading、error、refetch;通过 address、abi、functionName、args 调用。
useWriteContract(替代 useContractWrite)
写入合约,返回 hash、writeContract、isPending、error;常配合 useWaitForTransactionReceipt({ hash }) 等待交易确认(isLoading、isSuccess)。
使用方式
1. Config 配置
使用 createConfig 与 http 定义链与传输,链可来自 wagmi/chains(如 mainnet、polygon、arbitrum)。v3 中连接器需单独安装:npm i @wagmi/connectors,并从中引入 injected、coinbaseWallet、walletConnect 等。
// config.ts
import { http, createConfig } from 'wagmi'
import { mainnet, polygon, arbitrum } from 'wagmi/chains'
import { injected, coinbaseWallet, walletConnect } from '@wagmi/connectors'
export const config = createConfig({
chains: [mainnet, polygon, arbitrum],
connectors: [
injected(),
coinbaseWallet({ appName: 'My App' }),
walletConnect({ projectId: 'YOUR_PROJECT_ID' }),
],
transports: {
[mainnet.id]: http('https://eth-mainnet.g.alchemy.com/v2/KEY'),
[polygon.id]: http('https://polygon-mainnet.g.alchemy.com/v2/KEY'),
[arbitrum.id]: http('https://arb-mainnet.g.alchemy.com/v2/KEY'),
},
})
v3 说明:连接器现位于 @wagmi/connectors 包中,以便更好地控制依赖。
2. Provider 配置
需要 WagmiProvider 与 TanStack Query 的 QueryClientProvider 配合。Next.js App Router 需加 'use client'。
// providers.tsx
'use client' // Required for Next.js App Router
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config'
const queryClient = new QueryClient()
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</WagmiProvider>
)
}
关键模式
ABI 类型安全(关键)
ABI 需使用 as const 才能获得完整类型推断;缺少 as const 会失去类型推断。
// ✅ CORRECT - as const for full type inference
const abi = [
{
name: 'transfer',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
outputs: [{ name: '', type: 'bool' }],
},
] as const
// ❌ WRONG - no type inference
const abi = [{ ... }] // Missing `as const`
禁止条件式调用 hooks
不要条件式调用 hooks,应使用 enabled 选项控制是否执行请求。
// ❌ WRONG - Violates Rules of Hooks
function BadComponent({ shouldFetch }) {
if (shouldFetch) {
const { data } = useReadContract({ ... })
}
}
// ✅ CORRECT - Use enabled option
function GoodComponent({ shouldFetch }) {
const { data } = useReadContract({
...params,
query: { enabled: shouldFetch },
})
}
避免陈旧闭包
注意闭包捕获的旧值问题。
// ❌ WRONG - Captures stale values
function BadComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
// This captures `amount` at render time!
const handleClick = () => {
writeContract({
...params,
args: [amount], // May be stale!
})
}
}
// ✅ CORRECT - Pass fresh values
function GoodComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
const handleClick = () => {
writeContract({
...params,
args: [amount], // Fresh from closure
})
}
}
常见错误与修正
- 使用 useContractRead(v1)→ 改用 useReadContract
- 使用 useContractWrite(v1)→ 改用 useWriteContract
- 从 useConnect 获取 connectors(v2)→ 改用 useConnectors() hook(v3)
- 从 useSwitchChain 获取 chains(v2)→ 改用 useChains() hook(v3)
- 条件式 hooks → 使用 query: { enabled: bool }
- 缺少 QueryClientProvider → Wagmi 依赖 TanStack Query
- 未等待 hash → 使用 useWaitForTransactionReceipt
- 使用字符串金额 → 使用 BigInt:1000n
- 从 wagmi/connectors 引入连接器 → v3 使用 @wagmi/connectors 包
参考资料
技能内列出的参考包括:references/hooks-guide.md(完整 hooks 参考)、references/react-patterns.md(React 专属模式与 SSR)、Wagmi 官方文档、Wagmi GitHub 源码与发布、以及 v2 到 v3 迁移的破坏性变更说明。
限制
资料中未提供价格、收费模式、平台支持范围、性能数据等具体信息;安装与使用中涉及的 RPC、projectId 等需由使用者自行配置。