概況
web3-react是由Noah Zinsmeister開發的一個web3框架,主要功能是實時獲取DApp裡的關鍵資料(如使用者當前連線的地址、網路、餘額等)。
Noah也是著名的去中心化交易所uniswap裡的工程師,因此這個庫在uniswap裡也已被大量的使用。
web3-react有兩個版本,V6和V8,先把這兩個版本的倉庫地址都貼一下:
V6:https://github.com/Uniswap/web3-react/tree/v6
V8:https://github.com/Uniswap/web3-react/tree/main
搜了下網上的大部分教程都是針對V6的,V8的很少,官方文件內容也不多。所以這篇文章是基於最新的V8版本的實踐教程。
安裝
第一步自然需要一個react專案,用create-react-app生成就好了。然後安裝@web3-react所需要的依賴。
"@walletconnect/web3-provider": "^1.7.1", "@web3-react/coinbase-wallet": "^8.0.33-beta.0", "@web3-react/core": "8.0.35-beta.0", "@web3-react/gnosis-safe": "^8.0.5-beta.0", "@web3-react/metamask": "8.0.29-beta.0", "@web3-react/network": "^8.0.26-beta.0", "@web3-react/types": "^8.0.19-beta.0", "@web3-react/walletconnect": "^8.0.34-beta.0",
使用
以連線metamask為例,先建立一個聯結器(connector),並將這個聯結器物件匯出。
import { initializeConnector } from '@web3-react/core' import { MetaMask } from '@web3-react/metamask' export const [metaMask, hooks] = initializeConnector<MetaMask>((actions) => new MetaMask({ actions }))
上面這個connector暴露了兩個屬性,hooks和metaMask,透過hooks就可以獲取到當前賬戶的關鍵資訊,比如
獲取當前網路的chainId
const chainId = useChainId()
獲取當前連線的賬戶地址
const accounts = useAccounts()
獲取當前賬戶的連線狀態
const isActive = useIsActive()
可以將上述值傳給一個容器元件
const { useChainId, useAccounts, useIsActivating, useIsActive, useProvider, useENSNames } = hooks export default function MetaMaskCard() { const chainId = useChainId() const accounts = useAccounts() const isActivating = useIsActivating() const isActive = useIsActive() const provider = useProvider() const ENSNames = useENSNames(provider) const [error, setError] = useState(undefined) // attempt to connect eagerly on mount useEffect(() => { void metaMask.connectEagerly().catch(() => { console.debug('Failed to connect eagerly to metamask') }) }, []) return ( <Card connector={metaMask} chainId={chainId} isActivating={isActivating} isActive={isActive} error={error} setError={setError} accounts={accounts} provider={provider} ENSNames={ENSNames} /> ) }
容器元件Card:
export function Card({ connector, chainId, isActivating, isActive, error, setError, ENSNames, accounts, provider, }: Props) { return ( <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', width: '500px', padding: '20px', margin: '20px', overflow: 'auto', border: '1px solid', borderRadius: '10px', }} > {/* <b>{getName(connector)}</b> */} <div style={{ marginBottom: '1rem' }}> <Status isActivating={isActivating} isActive={isActive} error={error} /> </div> <Chain chainId={chainId} /> <div style={{ marginBottom: '1rem' }}> <Accounts accounts={accounts} provider={provider} ENSNames={ENSNames} /> </div> <ConnectWithSelect connector={connector} chainId={chainId} isActivating={isActivating} isActive={isActive} error={error} setError={setError} /> </div> ) }
最終出來的效果,樣式可能不太美觀,關注功能點就好~
預設未登入:
點選登入,登入後的狀態:
預設是在主網,還能切換到別的網路
可以看到,切換網路後,餘額也實時發生了變化。
和web3Modal對比
有些小夥伴可能有疑惑,要連線錢包的話,用web3Modal就可以實現了,樣式還更美觀,為什麼要多此一舉用web3-react呢?
這是因為:
1. web3modal沒有提供能直接獲取地址,餘額和狀態的hooks,需要自己去呼叫api才能獲取。
2. 要切換網路的話,用web3modal還得自己去寫switch函式,用起來不夠方便。
從v6升級
雖然web3-react的內部在v6和v8之間發生了相當大的變化,但升級時改變也不太多。遷移到新的聯結器和狀態管理模式後,就能夠使用@web3-react/core中定義的hooks,特別是useWeb3React
。
v8的最大好處是鉤子現在是per-connector,而不是全域性鉤子,因此不再需要在聯結器/多個根之間進行混合了。