Commit a5b15e37 authored by Moody Salem's avatar Moody Salem

fix(application state): fix block number updates after changing networks

parent 2408b296
import { useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import useDebounce from '../../hooks/useDebounce'
import useIsWindowVisible from '../../hooks/useIsWindowVisible' import useIsWindowVisible from '../../hooks/useIsWindowVisible'
import { updateBlockNumber } from './actions' import { updateBlockNumber } from './actions'
import { useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
...@@ -10,41 +9,46 @@ export default function Updater() { ...@@ -10,41 +9,46 @@ export default function Updater() {
const dispatch = useDispatch() const dispatch = useDispatch()
const windowVisible = useIsWindowVisible() const windowVisible = useIsWindowVisible()
const [maxBlockNumber, setMaxBlockNumber] = useState<number | null>(null)
// because blocks arrive in bunches with longer polling periods, we just want
// to process the latest one.
const debouncedMaxBlockNumber = useDebounce<number | null>(maxBlockNumber, 100)
// update block number const [state, setState] = useState<{ chainId: number | undefined; blockNumber: number | null }>({
useEffect(() => { chainId,
if (!library || !chainId) return blockNumber: null
const blockListener = (blockNumber: number) => {
setMaxBlockNumber(maxBlockNumber => {
if (typeof maxBlockNumber !== 'number') return blockNumber
return Math.max(maxBlockNumber, blockNumber)
}) })
const blockNumberCallback = useCallback(
(blockNumber: number) => {
setState(state => {
if (chainId === state.chainId) {
if (typeof state.blockNumber !== 'number') return { chainId, blockNumber }
return { chainId, blockNumber: Math.max(blockNumber, state.blockNumber) }
} }
return state
})
},
[chainId, setState]
)
setMaxBlockNumber(null) // attach/detach listeners
useEffect(() => {
if (!library || !chainId || !windowVisible) return
setState({ chainId, blockNumber: null })
library library
.getBlockNumber() .getBlockNumber()
.then(blockNumber => dispatch(updateBlockNumber({ chainId, blockNumber }))) .then(blockNumberCallback)
.catch(error => console.error(`Failed to get block number for chainId ${chainId}`, error)) .catch(error => console.error(`Failed to get block number for chainId: ${chainId}`, error))
library.on('block', blockListener) library.on('block', blockNumberCallback)
return () => { return () => {
library.removeListener('block', blockListener) library.removeListener('block', blockNumberCallback)
} }
}, [dispatch, chainId, library]) }, [dispatch, chainId, library, blockNumberCallback, windowVisible])
useEffect(() => { useEffect(() => {
if (!chainId || !debouncedMaxBlockNumber) return if (!state.chainId || !state.blockNumber || !windowVisible) return
if (windowVisible) { dispatch(updateBlockNumber({ chainId: state.chainId, blockNumber: state.blockNumber }))
dispatch(updateBlockNumber({ chainId, blockNumber: debouncedMaxBlockNumber })) }, [windowVisible, dispatch, state.blockNumber, state.chainId])
}
}, [chainId, debouncedMaxBlockNumber, windowVisible, dispatch])
return null return null
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment