
wagmi 中 useWatchBlockNumber Hook 完全指南实时监听区块号变化【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi本指南系统讲解 wagmi React 包中useWatchBlockNumberHook 的用法它用于持续监听链上区块号变化并在新块出现时触发回调是构建区块确认进度条、链上事件实时同步、交易等待提示等实时场景的核心原语。读完本文你将掌握该 Hook 的完整参数体系、与底层watchBlockNumberAction 及 viem 的调用链关系并能直接照搬可运行的代码示例到自己的 dApp 中。概览useWatchBlockNumber是一个响应式原语Reactive primitive你只需要声明式地传入回调Hook 会在背后自动管理订阅生命周期——包括在组件卸载时清理监听、在依赖变化时重新订阅。其底层直接包装了wagmi/core的watchBlockNumberAction而该 Action 又通过getAction代理到 viem 的同名watchBlockNumber公共 Action形成完整的调用链。import { useWatchBlockNumber } from wagmi基本用法最简用法只需提供一个onBlockNumber回调每次链上产生新块时回调都会被触发并携带最新的区块号bigint类型import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(Block number changed!, blockNumber) }, }) }使用前需要在应用根部配置好WagmiProvider与config一个同时连接主网与 Sepolia 的示例配置见 site/snippets/react/config.tsimport { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })从源码看packages/react/src/hooks/useWatchBlockNumber.tsHook 内部通过useEffect调用watchBlockNumber(config, {...})并将返回值作为 effect 的清理函数因此订阅会随组件卸载自动解除。参数Parameters完整的参数类型来自UseWatchBlockNumberParametersimport { type UseWatchBlockNumberParameters } from wagmi该类型是WatchBlockNumberParameters、ConfigParameter与EnabledParameter的交集UnionExactPartial使其所有字段均可选因此几乎所有参数都有默认行为。下面逐一说明。chainId类型config[chains][number][id] | undefined要监听区块的链 ID。不传时默认使用当前连接的链由useChainId提供见源码第 41-42 行传参则强制监听指定链import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ chainId: 1, onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }config类型Config | undefined显式传入Config以替代从最近的WagmiProvider自动获取的配置实例。适用于脱离 Provider 或在测试等特殊场景下使用import { useWatchBlockNumber } from wagmi import { config } from ./config function App() { useWatchBlockNumber({ config, onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }emitMissed类型boolean默认值false是否把错过的区块也补发给回调。所谓错过通常发生在网络断连或区块出块时间小于客户端轮询间隔的情况下——例如你在轮询期间断网恢复后区块号已经跳了几格开启此选项后这些中间区块号会依次补发import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ emitMissed: true, onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }emitOnBegin类型boolean默认值false订阅建立时是否立即把当前最新区块号发给回调一次。这对于订阅即取当前值的场景很有用例如初始化页面数据import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ emitOnBegin: true, onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }enabled类型boolean默认值true是否开启监听。设为false时 Hook 不建立任何订阅源码中if (!enabled) return直接跳过 effect可用于按需暂停监听如钱包未连接时import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ enabled: false, onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }onBlockNumber类型(block: Block, prevblock: Block | undefined) void区块变化时触发的回调。第一个参数是最新区块号bigint第二个参数是上一个区块号首次触发时为undefinedimport { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, }) }这里有两个值得注意的源码实现细节见 useWatchBlockNumber.ts回调使用 ref 持有onBlockNumberRef与onErrorRef每次渲染都会更新为最新闭包但 effect 的依赖数组只包含emitMissed、emitOnBegin、poll、pollingInterval、syncConnectedChain等配置项不含回调本身。这意味着更换回调函数不会导致重复订阅。测试 useWatchBlockNumber.test.ts 专门验证了这一行为连续多次rerender传入新回调后挖两个块只收到 2 次回调证明没有发生重复订阅另一条用例则验证新回调会被立即采用。onError类型((error: Error) void) | undefined获取区块号过程中抛出错误时的回调用于错误上报或降级提示import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, onError(error) { console.error(Block error, error) }, }) }poll类型boolean | undefined是否使用轮询机制检查新块而非 WebSocket 订阅。默认值取决于 Client 的传输类型WebSocket Client 默认false走实时订阅非 WebSocket Client如 HTTP默认true走轮询。import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, poll: true, }) }类型系统层面poll的合法取值会随 transport 收紧类型测试 useWatchBlockNumber.test-d.ts 展示了——当 config 为主网配http()、Optimism 配webSocket()时在指定chainId: mainnet.id的情况下poll: false会被ts-expect-error标记为类型错误HTTP transport 不支持关闭轮询而 Optimism 上poll仍为boolean | undefined。这正是 viemWatchBlockNumberParameters泛型随 transport 收窄的体现。pollingInterval类型number | undefined轮询频率毫秒。默认继承 Config 的pollingIntervalimport { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, pollingInterval: 1_000, }) }syncConnectedChain类型boolean | undefined是否为已连接链变化建立订阅。默认继承Config[syncConnectedChain]。开启后当用户切换连接的网络时监听会自动转移到新链上import { useWatchBlockNumber } from wagmi function App() { useWatchBlockNumber({ onBlockNumber(blockNumber) { console.log(New block number, blockNumber) }, syncConnectedChain: false, }) }该行为在底层 Action 中有明确实现见 watchBlockNumber.ts当syncConnectedChain为真且未显式传chainId时会通过config.subscribe(({ chainId }) chainId, ...)订阅链变化并在切换时先unwatch()旧监听、再对新链重新建立监听。返回类型Return Typeimport { type UseWatchBlockNumberReturnType } from wagmi该 Hook 的返回类型为void——订阅生命周期完全交由 Hook 内部管理无需手动清理卸载时自动解除。底层 ActionwatchBlockNumber如果你需要在 React 之外或使用 Solid、Vue 等框架监听区块号可以直接使用底层 Action见 packages/core/src/actions/watchBlockNumber.tsimport { watchBlockNumber } from wagmi/core import { config } from ./config const unwatch watchBlockNumber(config, { onBlockNumber(blockNumber) { console.log(Block number changed!, blockNumber) }, }) // 需要时手动停止监听 unwatch()Action 的实现要点对照源码通过config.getClient({ chainId })获取指定链的 viem Client借助getAction见 packages/core/src/utils/getAction.ts优先取 Client 上已有的同名 action允许用户覆盖实现否则回退到 tree-shakable 的 viemwatchBlockNumber返回的unwatch函数会同时清理监听与链切换订阅保证不泄漏。核心测试 watchBlockNumber.test.ts 验证了默认行为连续mine({ blocks: 1 })三次后回调累计收到 3 个区块号随后unwatch()停止接收。该 Action 的完整参数说明chainId、emitOnBegin、emitMissed、onBlockNumber、onError、poll、pollingInterval、syncConnectedChain与 Hook 一一对应详见 site/core/api/actions/watchBlockNumber.md。多框架支持同名能力在仓库的其他框架适配中也有对应实现API 设计保持一致Solidpackages/solid/src/primitives/useWatchBlockNumber.ts使用createEffectonCleanup管理订阅参数以Accessor形式传入Vuepackages/vue/src/composables/useWatchBlockNumber.ts使用watchEffect管理订阅参数支持响应式 ref内部通过deepUnref解包。常见问题与最佳实践回调更新不会造成重复订阅得益于 ref 持有回调的机制你可以在渲染中放心内联新的onBlockNumber/onError函数无需useCallback包裹。暂停/恢复监听用enabled按需切换enabled即可建立或销毁订阅避免手动管理 unwatch。固定监听某条链用chainId当监听目标与当前连接链不一致如始终盯主网时显式传入chainId。WebSocket 传输可关闭轮询只有 transport 为 WebSocket 时poll: false才有类型意义HTTP transport 下类型系统会强制轮询。补块场景开启emitMissed对区块号连续性敏感的应用如索引器、对账逻辑建议开启避免断网期间丢块。小结useWatchBlockNumber以最小的声明式接口封装了监听区块号这一高频链上需求九个参数chainId、config、emitMissed、emitOnBegin、enabled、onBlockNumber、onError、poll、pollingInterval、syncConnectedChain覆盖了目标链选择、传输方式、补块、错误处理、暂停开关等全部实际诉求底层则完整复用了wagmi/core的watchBlockNumberAction 与 viem 的公共 Action并通过 ref 化回调与依赖数组设计保证了订阅的高效与安全。配套的单元测试与类型测试useWatchBlockNumber.test.ts、useWatchBlockNumber.test-d.ts可帮助你进一步确认各参数的真实行为。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考