fix: restructure web3 to memoize (#3472)
This commit is contained in:
parent
96c66a5846
commit
32f955693f
@ -1,40 +0,0 @@
|
||||
import { initializeConnector } from '@web3-react/core'
|
||||
import { EIP1193 } from '@web3-react/eip1193'
|
||||
import { Actions, Connector, Provider as Eip1193Provider } from '@web3-react/types'
|
||||
import { Url } from '@web3-react/url'
|
||||
import { SetStateAction } from 'jotai'
|
||||
import { RESET, useUpdateAtom } from 'jotai/utils'
|
||||
import { injectedAtom, urlAtom, Web3ReactState } from 'lib/state/web3'
|
||||
import { ReactNode, useEffect } from 'react'
|
||||
|
||||
interface Web3ProviderProps {
|
||||
jsonRpcEndpoint?: string
|
||||
provider?: Eip1193Provider
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
function useConnector<T extends { new (actions: Actions, initializer: I): Connector }, I>(
|
||||
Connector: T,
|
||||
initializer: I | undefined,
|
||||
setContext: (update: typeof RESET | SetStateAction<Web3ReactState>) => void
|
||||
) {
|
||||
return useEffect(() => {
|
||||
if (initializer) {
|
||||
const state = initializeConnector((actions) => new Connector(actions, initializer))
|
||||
state[0].activate()
|
||||
setContext(state)
|
||||
} else {
|
||||
setContext(RESET)
|
||||
}
|
||||
}, [Connector, initializer, setContext])
|
||||
}
|
||||
|
||||
export default function Web3Provider({ jsonRpcEndpoint, provider, children }: Web3ProviderProps) {
|
||||
const setUrl = useUpdateAtom(urlAtom)
|
||||
useConnector(Url, jsonRpcEndpoint, setUrl)
|
||||
|
||||
const setInjected = useUpdateAtom(injectedAtom)
|
||||
useConnector(EIP1193, provider, setInjected)
|
||||
|
||||
return <>{children}</>
|
||||
}
|
@ -3,6 +3,7 @@ import { Provider as Eip1193Provider } from '@web3-react/types'
|
||||
import { DEFAULT_LOCALE, SupportedLocale } from 'constants/locales'
|
||||
import { Provider as AtomProvider } from 'jotai'
|
||||
import { TransactionsUpdater } from 'lib/hooks/transactions'
|
||||
import { Web3Provider } from 'lib/hooks/useActiveWeb3React'
|
||||
import { BlockUpdater } from 'lib/hooks/useBlockNumber'
|
||||
import useEip1193Provider from 'lib/hooks/useEip1193Provider'
|
||||
import { UNMOUNTING } from 'lib/hooks/useUnmount'
|
||||
@ -15,7 +16,6 @@ import { Provider as ReduxProvider } from 'react-redux'
|
||||
import { Modal, Provider as DialogProvider } from './Dialog'
|
||||
import ErrorBoundary, { ErrorHandler } from './Error/ErrorBoundary'
|
||||
import WidgetPropValidator from './Error/WidgetsPropsValidator'
|
||||
import Web3Provider from './Web3Provider'
|
||||
|
||||
const WidgetWrapper = styled.div<{ width?: number | string }>`
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { Web3ReactHooks } from '@web3-react/core'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import { injectedAtom, urlAtom, Web3ReactState } from 'lib/state/web3'
|
||||
|
||||
export function useActiveWeb3ReactState(): Web3ReactState {
|
||||
const injected = useAtomValue(injectedAtom)
|
||||
const url = useAtomValue(urlAtom)
|
||||
return injected[1].useIsActive() ? injected : url
|
||||
}
|
||||
|
||||
export function useActiveWeb3ReactHooks(): Web3ReactHooks {
|
||||
const [, hooks] = useActiveWeb3ReactState()
|
||||
return hooks
|
||||
}
|
||||
|
||||
export default function useActiveWeb3React() {
|
||||
const { useProvider, useWeb3React } = useActiveWeb3ReactHooks()
|
||||
return useWeb3React(useProvider())
|
||||
}
|
63
src/lib/hooks/useActiveWeb3React.tsx
Normal file
63
src/lib/hooks/useActiveWeb3React.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { getPriorityConnector, initializeConnector, Web3ReactHooks } from '@web3-react/core'
|
||||
import { EIP1193 } from '@web3-react/eip1193'
|
||||
import { EMPTY } from '@web3-react/empty'
|
||||
import { Actions, Connector, Provider as Eip1193Provider } from '@web3-react/types'
|
||||
import { Url } from '@web3-react/url'
|
||||
import { useAtom, WritableAtom } from 'jotai'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import { atomWithDefault, RESET, useUpdateAtom } from 'jotai/utils'
|
||||
import { PropsWithChildren, useEffect } from 'react'
|
||||
|
||||
const [connector, hooks] = initializeConnector(() => EMPTY)
|
||||
const EMPTY_CONNECTOR: [Connector, Web3ReactHooks] = [connector, hooks]
|
||||
const urlConnectorAtom = atomWithDefault<[Connector, Web3ReactHooks]>(() => EMPTY_CONNECTOR)
|
||||
const injectedConnectorAtom = atomWithDefault<[Connector, Web3ReactHooks]>(() => EMPTY_CONNECTOR)
|
||||
const web3Atom = atomWithDefault<ReturnType<typeof hooks.useWeb3React>>(() => ({
|
||||
connector: EMPTY_CONNECTOR[0],
|
||||
library: undefined,
|
||||
chainId: undefined,
|
||||
account: undefined,
|
||||
active: false,
|
||||
error: undefined,
|
||||
}))
|
||||
|
||||
export default function useActiveWeb3React() {
|
||||
return useAtomValue(web3Atom)
|
||||
}
|
||||
|
||||
function useConnector<T extends { new (actions: Actions, initializer: I): Connector }, I>(
|
||||
connectorAtom: WritableAtom<[Connector, Web3ReactHooks], typeof RESET | [Connector, Web3ReactHooks]>,
|
||||
Connector: T,
|
||||
initializer: I | undefined
|
||||
) {
|
||||
const [connector, setConnector] = useAtom(connectorAtom)
|
||||
useEffect(() => {
|
||||
if (initializer) {
|
||||
const [connector, hooks] = initializeConnector((actions) => new Connector(actions, initializer))
|
||||
connector.activate()
|
||||
setConnector([connector, hooks])
|
||||
} else {
|
||||
setConnector(RESET)
|
||||
}
|
||||
}, [Connector, initializer, setConnector])
|
||||
return connector
|
||||
}
|
||||
|
||||
interface Web3ProviderProps {
|
||||
provider?: Eip1193Provider
|
||||
jsonRpcEndpoint?: string
|
||||
}
|
||||
|
||||
export function Web3Provider({ provider, jsonRpcEndpoint, children }: PropsWithChildren<Web3ProviderProps>) {
|
||||
const injectedConnector = useConnector(injectedConnectorAtom, EIP1193, provider)
|
||||
const urlConnector = useConnector(urlConnectorAtom, Url, jsonRpcEndpoint)
|
||||
const priorityConnector = getPriorityConnector(injectedConnector, urlConnector)
|
||||
const priorityProvider = priorityConnector.usePriorityProvider()
|
||||
const priorityWeb3React = priorityConnector.usePriorityWeb3React(priorityProvider)
|
||||
const setWeb3 = useUpdateAtom(web3Atom)
|
||||
useEffect(() => {
|
||||
setWeb3(priorityWeb3React)
|
||||
}, [priorityWeb3React, setWeb3])
|
||||
|
||||
return <>{children}</>
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { initializeConnector, Web3ReactHooks } from '@web3-react/core'
|
||||
import { EMPTY } from '@web3-react/empty'
|
||||
import { Connector, Web3ReactStore } from '@web3-react/types'
|
||||
import { atomWithDefault } from 'jotai/utils'
|
||||
|
||||
export type Web3ReactState = [Connector, Web3ReactHooks, Web3ReactStore]
|
||||
|
||||
const EMPTY_CONNECTOR = initializeConnector(() => EMPTY)
|
||||
|
||||
export const urlAtom = atomWithDefault<Web3ReactState>(() => EMPTY_CONNECTOR)
|
||||
export const injectedAtom = atomWithDefault<Web3ReactState>(() => EMPTY_CONNECTOR)
|
Loading…
Reference in New Issue
Block a user