-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useWatchBlocks
subscribes / unsubscribes on each new Block with WebSocket
#4352
Comments
After investigating the issue further, it seems that
is causing the behavior. The following change seems to help:
However, I suggest a code-change where modifying the callback is not causing a subscribe / unsubscribe. |
Just a quick draft on how this could be improved. Using a 'use client'
import {
type Config,
type ResolvedRegister,
type WatchBlocksParameters,
watchBlocks,
} from '@wagmi/core'
import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal'
import { useEffect, useRef, useState } from 'react'
import type { BlockTag, OnBlockParameter } from 'viem'
// Import wagmi config and constants for test
import { config } from '../AppKit'
export type EnabledParameter = {
enabled?: boolean | undefined
}
export type ConfigParameter<config extends Config = Config> = {
config?: Config | config | undefined
}
export type UseWatchBlocksParameters<
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
config extends Config = Config,
chainId extends
config['chains'][number]['id'] = config['chains'][number]['id'],
> = UnionCompute<
UnionExactPartial<
WatchBlocksParameters<includeTransactions, blockTag, config, chainId>
> &
ConfigParameter<config> &
EnabledParameter
>
export type UseWatchBlocksReturnType = void
/** https://wagmi.sh/react/hooks/useWatchBlocks */
export function useWatchBlocks<
config extends Config = ResolvedRegister['config'],
chainId extends
config['chains'][number]['id'] = config['chains'][number]['id'],
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
>(
parameters: UseWatchBlocksParameters<
includeTransactions,
blockTag,
config,
chainId
> = {} as any,
): UseWatchBlocksReturnType {
const { enabled = true, onBlock, config: _, ...rest } = parameters
const chainId = parameters.chainId
// Use a ref to hold the onBlock callback
const onBlockRef = useRef(onBlock)
const [watchEnabled, setWatchEnabled] = useState(enabled && !!onBlock)
// Update the ref if onBlock changes, but don't cause re-subscription
useEffect(() => {
console.log('UPDATE REF')
onBlockRef.current = onBlock
// Adjust watchEnabled when onBlock goes from undefined to defined or vice versa
if (!!onBlock !== watchEnabled) {
setWatchEnabled(!!onBlock)
}
}, [onBlock, watchEnabled])
useEffect(() => {
if (!watchEnabled) return
console.log('WATCH')
const unwatch = watchBlocks(config, {
...(rest as any),
chainId,
// Use the latest onBlock from the ref
onBlock: (block, prevBlock) => {
if (onBlockRef.current) {
onBlockRef.current(block, prevBlock)
}
},
})
return () => {
console.log('UNWATCH')
unwatch()
}
}, [
chainId,
config,
watchEnabled, // Dependency that changes based on whether we should be watching or not
///
rest.blockTag,
rest.emitMissed,
rest.emitOnBegin,
rest.includeTransactions,
rest.onError,
rest.poll,
rest.pollingInterval,
rest.syncConnectedChain,
])
} |
I cant reproduce ur issue, I dont see there're unsubscribe action on new block. Could you provide a reproduce example? |
@coderodigital unable to repro your issue Wagmi version -
where |
Let me prepare an example repo (give me a day). To identify the bug, you must examine the network traffic on the open WebSocket connection. The code works as intended but could be more effective when using the WebSocket subscription (which only subscribes once). I will also share screenshots of the network traffic. |
Check existing issues
Describe the bug
When using
useWatchBlocks
with a WebSocket connection, the expected behavior is as follows:onBlock
) callbacks without unsubscribinguseWatchBlocks
is unmounted / modifiedThe observed behavior is:
onBlock
useWatchBlocks
, probably caused byuseEffect
in theuseWatchBlocks
implementationIt's important to be aware that subscribing / Unsubscribing can be an expensive call on certain API providers (e.g. 10 Compute Units on Alchemy), causing unnecessary spikes in API Usage.
Alchemy Compute Unit Costs
Link to Minimal Reproducible Example
No response
Steps To Reproduce
useWatchBlocks
code to get console log outputsYou will observe that the subscription is closed after each block, and a new subscription is established.
Code to use the modified hook:
The modified hook:
What Wagmi package(s) are you using?
wagmi
Wagmi Package(s) Version(s)
2.12.17
Viem Version
2.21.21
TypeScript Version
5.6.0
Anything else?
No response
The text was updated successfully, but these errors were encountered: