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 { DEFAULT_LOCALE, SupportedLocale } from 'constants/locales'
|
||||||
import { Provider as AtomProvider } from 'jotai'
|
import { Provider as AtomProvider } from 'jotai'
|
||||||
import { TransactionsUpdater } from 'lib/hooks/transactions'
|
import { TransactionsUpdater } from 'lib/hooks/transactions'
|
||||||
|
import { Web3Provider } from 'lib/hooks/useActiveWeb3React'
|
||||||
import { BlockUpdater } from 'lib/hooks/useBlockNumber'
|
import { BlockUpdater } from 'lib/hooks/useBlockNumber'
|
||||||
import useEip1193Provider from 'lib/hooks/useEip1193Provider'
|
import useEip1193Provider from 'lib/hooks/useEip1193Provider'
|
||||||
import { UNMOUNTING } from 'lib/hooks/useUnmount'
|
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 { Modal, Provider as DialogProvider } from './Dialog'
|
||||||
import ErrorBoundary, { ErrorHandler } from './Error/ErrorBoundary'
|
import ErrorBoundary, { ErrorHandler } from './Error/ErrorBoundary'
|
||||||
import WidgetPropValidator from './Error/WidgetsPropsValidator'
|
import WidgetPropValidator from './Error/WidgetsPropsValidator'
|
||||||
import Web3Provider from './Web3Provider'
|
|
||||||
|
|
||||||
const WidgetWrapper = styled.div<{ width?: number | string }>`
|
const WidgetWrapper = styled.div<{ width?: number | string }>`
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-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