MWAN MOBILE

×
mwan_logo
blog-banner

What is Web3-React and How to use it for your dApp front-end?

Blockchain 30-Jan-2023

Are you building a dApp? If yes, then you must need to connect your dApp to a wallet. Web3-react might just be the tool you are looking for!

Web3-react is a web3 framework made by Noah Zinsmeister to help blockchain developers make modern Ethereum dApps using React hooks.

Let’s explore web3-react! πŸ‘‡β€

What is Web3-react?

Web3-react is a React-based framework that helps to ease the frontend development for your dApp.

Web3-react also acts as a state machine that maintains the data relevant to your dApp and injects it wherever needed in the component tree. Web3-React supports a wide range of wallets, from browser wallets like Metamask and Coinbase to hardware wallets like Trezor and Ledger.

In LearnWeb3, we use Web3-Modal for wallet connection in dApps. Web3-Modal is great for beginners, but as we scale our projects, handling Web3-Modal gets harder.

Thus web3-react can be a better option because:

  • It’s better for building modern dApps
  • Has a better developer experience
  • Reduces code redundancy
  • And is an intuitive framework to work with

Why using Web3-react might be a better idea?

Web3-React provides flexibility in many ways. It has great support for many wallets as discussed earlier.

But even if the wallet is not included in web3-react packages, you can create your custom connectors and connect wallets other than those listed with web3-react!

Web3-react uses Ethers.js or Web3.js under the hood thus providing a smooth experience as connecting wallet using only ether.js can be a really painful process.

Note: Before moving forward, make sure you understand ContextAPI in other words, useContext hook. It is the key feature of Web3-React.

Installing web3-react

Let’s install web3-react!

In this article, we assume that you have your ReactJS/NextJS app already set up.

In your app directory, run the following command to install web-react:

COPYCOPYCOPY

npm install @web-react/core

or

COPYCOPYCOPY

yarn add @web3-react/core

Now, for connecting browser-based wallets, we need to install the following web3-react package:

COPYCOPYCOPY

npm install @web3-react/injected-connector

or

COPYCOPYCOPY

yarn add @web3-react/injected-connector

And.. you have all the ingredients required to connect your dApp to a browser wallet! Let’s start writing code to connect the wallet!

Connecting Wallet

This section assumes you have already created the app and installed the previous dependencies. Now that it’s taken care of, let’s get straight into this!

Step 1: Setting up Web3ReactProvider

Let’s jump into your _app.js(for Next) file under the pages folder!

Edit the code such that it looks like this πŸ‘‡β€

COPYCOPYCOPY

import '../styles/globals.css'
import { Web3ReactProvider } from '@web3-react/core'
import { providers, Web3Provider } from 'ethers'

function getLibrary(provider, connector) {
  return new providers.Web3Provider(provider)
}

function MyApp({ Component, pageProps }) {
  return(
    <Web3ReactProvider getLibrary={getLibrary}>
      <Component {...pageProps} />
    </Web3ReactProvider>
  )
}

export default MyApp

Done? Now let’s understand the code!

  • This function is returning the provider object.COPYCOPYCOPYfunction getLibrary(provider, connector) { return new providers.Web3Provider(provider) }
  • The Web3ReactProvider is the Context Provider which passes all the data down the component tree.COPYCOPYCOPYfunction MyApp({ Component, pageProps }) { return ( <Web3ReactProvider getLibrary={getLibrary}> <Component {...pageProps} /> </Web3ReactProvider> ) }

Step 2: Setting up the Hooks

Now let’s jump into your index.js in the pages folder.

COPYCOPYCOPY

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { InjectedConnector } from '@web3-react/injected-connector'
import { useWeb3React } from '@web3-react/core'
import { useState } from 'react'
import { CONTRACT_ADDRESS, CONTRACT_ABI } from '../constants'

export default function Home() {

  const [ result, setResult ] = useState("")

  // web3-react hook, helps in fetching 
  // the data passed by Web3ReactProvider
  const { active, activate, deactivate, account, library, connector, error } = useWeb3React()

  // injected provider identifier
  const injected = new InjectedConnector(
    {
      supportedChainIds:[80001]
    }
  )

  const connectWallet = async () => {
    try {
      await activate(injected)
    } catch (err) {
      console.error(err)
    }
  }

  const disconnectWallet = async () => {
    try {
      deactivate(injected)
    } catch (err) {
      console.error(err)
    }
  }
return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <button onClick={connectWallet}>Connect Wallet</button>
      {active? <span>Connected with <b>{account}</b></span>: <span>Not Connected</span>}
      <button onClick={disconnectWallet}>Disconnect Wallet</button>

    </div>
  )
}

Okay, so now let’s look at useWeb3React hook

COPYCOPYCOPY

const { active, activate, deactivate, account, library, connector, error } = useWeb3React()
  • useWeb3React is a custom hook from the web-react library that returns a lot of useful functionalities.
  • This hook returns:COPYCOPYCOPY connector; // connector object returns some useful connection // methods like activate() and deactivate() library; // library is the provider object that we // passed with the Web3ReactProvider chainId; // returns the chainId for the account that // is connected to the dApp account; // the account address of the connected account active; // active is a state variable which returns boolean values // that determines whether the wallet connection is // active or inactive error; // returns any error happening with the wallet connection

Now let’s look at the injected variable –

COPYCOPYCOPY

const injected = new InjectedConnector({
      supportedChainIds:[80001]
})
// we can list multiple networks by listing their
// chainIds, separated by comma
  • Injected Connector is a class that takes input for the supported chainIds and returns a set of methods to interact with browser wallets.
  • It will return an UnsupportedChainId error if the wallet is not connected to the right network. This error can be accessed from the error object returned by the useWeb3React hook.

As for the activate(injected) and deactivate(injected), they are methods that will connect or disconnect the injected provider (browser wallet).

And BOOMπŸ’₯ you have a wallet connection setup ready!

Reading and Writing in the Contract

Now that we have connected our wallets, all that is left is the way to read from and write to the blockchain!

How do we achieve that?

We will be using the web3-react library(provider) object to read/write from/on the blockchain

So, we are going to use the Mood dApp Contract that was built in LearnWeb3DAO’s Freshman Track. Click here to get the smart contract.

Before we go deeper into this, make sure you have made an index.js in the constants folder(in the root directory), and it should have the following code –

COPYCOPYCOPY

// put your contract address in place of this gibberish
export const CONTRACT_ADDRESS = "0xabcabcabcabcabcabc";

// put your abi in this variable, it will be of the form [{},{}]
export const CONTRACT_ABI = [...]

Reading

For reading from smart contracts, we need two things-

  • Contract Instance
  • Provider

So let’s write a function for reading from the smart contract!

COPYCOPYCOPY

const getMood = async () => {

    const provider = library;

    const contract = new Contract(
      CONRTACT_ADDRESS,
      CONTRACT_ABI,
      provider
    );

    const tx = await contract.getMood();
    tx.wait();
    setResult(tx);
  }
  • We are setting the provider variable to library. Remember, library was returned from the useWeb3React hook and it is a provider object. Handy, isn’t it?
  • Then, we create a new Contract instance, this enables us to interact with the contract.
  • Now it’s time to create a transaction! We are calling the getMood() function from the contract here.
  • tx.wait() waits for the transaction to complete.
  • setResult(tx) sets the value of the state variable result to tx‘s value.

Writing

For writing through the smart contracts, we need two things-

  • Contract Instance
  • Signer (to sign the transaction)

Let’s create a writing function!

COPYCOPYCOPY

const setMood = async ( mood ) => {

    const signer = await library.getSigner()

    const contract = new Contract(
      CONRTACT_ADDRESS,
      CONTRACT_ABI,
      signer
    )

    const tx = await contract.setMood(mood)
    tx.wait()
    alert("Mood set!")
  }

The things have changed now, let’s explore each of them step by step –

  • library is a provider object, but we needed a signer, right? Well, a provider object has a method called getSigner() that returns the signer object attached to this provider!
  • The contract is a Contract instance, but here, instead of passing the provider, we are passing a signer, because, for writing transactions, we need a signer to sign the transaction.
  • At last, we have now passed an argument to the contract function, because, the function from the contract takes an argument for setting a mood.

LFG!! You have made a dApp frontend with web3-react! It can read, and write on the blockchain too!πŸ’ͺ‍

Conclusion

Web3-react is a very handy framework for building the dApp frontend in React/NextJS.

It is a very easy-to-use tool, but it can be confusing for beginners. For using this tool, you may need some knowledge of Context API.

Note: The Web3-React is not well documented, and the main branch of their repo does not even have docs. For reading their docs, shift to their v6 branch.

That’s it for this blog!

See you around next time. πŸ˜„

Source: Learn Web3