Resources
Introduction
web3-react
is a drop in solution for building Ethereum dApps in React. Its marquee features are:
-
A large and fully extensible collection of Connectors, which manage connectivity with the Ethereum blockchain and user account(s). Connectors can make your dApp compatible with MetaMask, WalletConnect, Infura, Trust, and more.
-
A robust web3 management framework which exposes the current account, the current network ID, and an instantiated ethers.js or web3.js instance to your dapp via a React Context.
-
A collection of React Hooks that can be used to display ETH and ERC-20 balances, sign messages, send transactions, etc.
-
A number of utility functions to format Etherscan links, convert token balances, etc.
Implementations
Projects using web3-react
include:
Open a PR to add your project to the list! If you're interested in contributing, check out Contributing-Guidelines.md.
Quickstart
If you want to cut straight to the chase, check out the CodeSandbox demo!
1. Install
Since web3-react
uses Hooks, make sure that your project relies on the correct alpha builds of react
and react-dom
:
npm install react@16.7.0-alpha.2 react-dom@16.7.0-alpha.2
Then, get the npm package:
npm install web3-react@next
2. Setup Connectors
Now, decide how you want users to interact with your dApp. For the vast majority of dApps, this will be with some combination of MetaMask/Infura/WalletConnect. For more details see Connectors.md.
If you want web3-react
to try to automatically initialize some of your connectors, pass the optional automaticPriority
parameter to as many of your connectors as you want to try, where automaticPriority
is a number whose sort order determines the connector's precedence order.
Your connectors should end up looking something like the following:
import { MetaMaskConnector, InfuraConnector, WalletConnectConnector } from 'web3-react/connectors'
const connectors = {
metamask: new MetaMaskConnector(),
infura: new InfuraConnector({ providerURL: 'https://mainnet.infura.io/v3/<YOUR-API-KEY>' }),
walletConnect: new WalletConnectConnector({
providerURL: 'https://mainnet.infura.io/v3/<YOUR-API-KEY>',
dappName: '<YOUR-DAPP-NAME>', bridgeURL: 'https://test-bridge.walletconnect.org'
})
}
3. Setup Web3Provider
The next step is to setup a Web3Provider
at the root of your dApp. This ensures that children components are able to take advantage of the web3-react
context variables.
import React from 'react'
import Web3Provider from 'web3-react'
export default function App () {
return (
<Web3Provider
connectors={...}
passive={...}
...
>
...
</Web3Provider>
)
}
Web3Provider
takes 5 props:
-
connectors
(required): An object mapping connector names to Connectors (see the previous section).
-
passive
(required): Determines whether users must have an active Connector before using your dApp. Passing true
means that the InitializingWeb3
screen will be (at least initially) bypassed and all web3-react
context variables will be inactive. In order to activate the context, call activate
or setConnector
. Passing false
means that web3-react
will try to automatically initialize connectors if any are set, or show the InitializingWeb3
screen.
-
screens
(optional): React Components which will be displayed according to the user's current status. Note that these screens are lazily loaded with React.lazy, and therefore are not SSR-compatible.
-
InitializingWeb3
: Shown when users are picking between Connectors, or while a Connector is being initialized. It takes props as defined in the source code (docs forthcoming).
-
Web3Error
: Shown whenever an error occurs. It takes props as defined in the source code (docs forthcoming).
-
libraryName
(optional): web3.js
or ethers.js
, depending on which library you wish to use in your dApp.
-
children
(required): The rest of your dApp.
4. Using web3-react
Finally, you're ready to use web3-react
!
Recommended - Hooks
The easiest way to use web3-react
is with Hooks.
import React from 'react'
import { useWeb3Context, useAccountBalance } from 'web3-react/hooks'
function MyComponent () {
const context = useWeb3Context()
const balance = useAccountBalance()
return (
<>
<p>{context.account}</p>
<p>{balance}</p>
</>
)
}
For more details see Hooks.md.
Conditionally Recommended - Render Props
To use web3-react
with render props, wrap Components in a Web3Consumer
. It takes two props:
-
recreateOnNetworkChange
(optional, default true
). A flag that controls whether child components are freshly re-initialized upon network changes.
-
recreateOnAccountChange
(optional, default true
). A flag that controls whether child components are freshly re-initialized upon account changes.
Note: Re-initialization is often the desired behavior, though properly written Hooks do not require these flags to be set.
import React from 'react'
import { Web3Consumer } from 'web3-react'
function AccountComponent (props) {
const { account } = props
return <p>{account}</p>
}
function MyComponent () {
return (
<Web3Consumer>
{context =>
<AccountComponent account={context.account} />
}
</Web3Consumer>
)
}
Note: This pattern will work for arbitrarily deeply nested components. This means that the Web3Consumer
doesn't necessarily need to be at the top level of your app. There also won't be performance concerns if you choose to use multiple Web3Consumer
s at different nesting levels.
Not Recommended - HOCs
If you must, you use web3-react
with an HOC. The withWeb3
wrapper's second argument can optionally be the recreate flags from the render props pattern.
import React from 'react'
import { withWeb3 } from 'web3-react'
function MyComponent (props) {
const { web3 } = props
const { account } = web3
return <p>{account}</p>
}
export default withWeb3(MyComponent)
Note: The high-level component which includes your Web3Provider
Component cannot be wrapped with withWeb3
.
Context
Regardless of how you inject the context, it looks like:
{
library : Library
networkId : number
account : string | null
networkReRenderer : number
forceNetworkReRender: Function
accountReRenderer : number
forceAccountReRender: Function
connectorName : string
activate : Function
activateAccount : Function
setConnector : Function
resetConnectors : Function
}
Variables
library
: A web3.js or ethers.js instance instantiated with the current web3 provider.networkId
: The current active network ID.account
: The current active account.
Renderers
These variables/functions facilitate the re-rendering of data derived from account
or networkId
(such as a user's balance, which can change over time without their actual account
changing). For how to use these reRenderers, see src/web3Hooks.ts. useAccountEffect
and useNetworkEffect
convenience wrappers for useEffect
are available as named exports of web3-react/hooks
; they take care of re-renders automatically.
accountReRenderer
: Forces re-renders of account-derived data when included in useEffect
hook depends arrays.forceAccountReRender
: A function that triggers a global re-render for Hooks depending on accountReRenderer
.networkReRenderer
: Forces re-renders of network-derived data when included in useEffect
hook depends arrays.forceNetworkReRender
: A function that triggers a global re-render for Hooks depending on networkReRenderer
.
Manager Functions
connectorName
: The name of the current, active connector.activate()
: Callable only when passive
is true and web3-react
is uninitialized, this triggers activation, which either shows the InitializingWeb3
screen, or tries each automaticPriority
connector and reacts accordingly.activateAccount()
: Callable only when activateAccountAutomatically
is set to false for the active connector, and the account has not yet been loaded. Triggers a call to the getAccount
method of the active connector.setConnector(connectorName)
: Activates a connector.resetConnectors(tryAutomaticAgain, deactivate)
: Resets connectors. tryAutomaticAgain
controls whether automatic connectors are attempted, and deactivate
controls whether the application is brought back into a passive
state.
Utility Functions
Documentation for the utility functions exported by web3-react
can be found in Utilities.md.
Hooks
Documentation for the hooks exported by web3-react
can be found in Hooks.md.
Notes
Prior art for web3-react
includes: