The React Truffle box, by default, attempts to connect to Web3 as soon as the page loads. This stifles user experience if the user isn’t logged onto MetaMask or is configured to a blockchain on which the DApp isn’t deployed.
Proposal: Blockchain ➼ account ➼ interaction
Instead of loading everything at once, I propose the following pattern for loading your DApp: blockchain ➼ account ➼ interaction. Each step is distinct from the other, with explicit visual feedback for the user.
In this example, there’s a single contract and a DApp front end for that contract. Before the user can interact with the contract, they need to connect to the blockchain (I’m using a
localhost blockchain here, provided by Ganache).
Several things happened here:
- When the page loads, Web3 is not loaded
- Blockchain — The user clicks “Connect Blockchain” to connect the webpage to their chosen blockchain in MetaMask
- Account — Once loaded, the application provides a second button to connect their wallet
- Interaction — The user is now able to interact with the DApp
Connecting the blockchain
Using Bootstrap, we can give visual feedback to the user as to whether their chosen blockchain is connected. In Figure 1, the
btn-danger when it’s yet to be loaded and
disabled classes when it is. Web3 represents a Redux state selector.
onSubmit action grabs the Web3 instance with an interaction, which is displayed in Figure 2. It dispatches the
web3Loaded(web3) reducer, which saves the Web3 instance to the state.
Connecting the account
Figure 3 shows a similar rendering, where we apply similar rules to the “Connect Wallet” button depending on if an account has been loaded already. This time, however, if Web3 is loaded, we apply an extra condition on whether or not an account is loaded:
(account !== null) ? “btn-success” : “btn-warning”
onSubmit action is a function that calls an interaction called
loadBlockchainData(), as seen in Figure 4.
Figure 4 shows
loadBlockchainData(), which in turn calls
loadAccount() on its first line. This function gets the account provided by MetaMask and dispatches an action called
accountLoaded(), which stores the account in our state via a reducer.
Once these steps are complete, the rest of the interface is enabled, and the user is free to interact with the DApp.
Using MetaMask with DApps can be a jittery experience that could deter users from interacting with your DApp. Use simple flows like
Blockchain-Account-Interaction to ease your users in.