Integrating Ether.js with React: A Comprehensive Guide

Building Powerful Ethereum-Powered Apps with React and Ether.js: A Beginner-Friendly Guide

Williams Peter
Coinmonks
Published in
5 min readJul 12, 2023

--

ethers.js

Introduction

Building decentralized applications (DApps) on the Ethereum blockchain requires a reliable and efficient way to interact with smart contracts. Ethers.js is a popular JavaScript library that provides a powerful and user-friendly interface for developers to interact with Ethereum networks. When combined with React, a widely adopted JavaScript library for building user interfaces, Ethers.js becomes an invaluable tool for creating seamless and interactive DApps. In this article, we will explore the process of integrating Ethers.js with React, covering the essential concepts and methods that every developer should know. We will also provide practical code samples that can help you get started on your journey.

Getting Started with Ethers.js

Before we dive into integrating Ethers.js with React, it’s essential to have a basic understanding of the core concepts and features of Ethers.js itself. Ethers.js is a powerful JavaScript library that allows developers to interact with Ethereum networks. It provides a wide range of functionalities, including account management, transaction signing, contract deployment, and interaction with smart contracts.

To get started, you can install Ethers.js using npm or yarn:

npm install ethers

Once installed, you can import Ethers.js into your project.

import { ethers } from 'ethers';

Setting Up a React Project

Assuming you have Node.js and npm installed, let’s set up a new React project to integrate Ethers.js. Open your terminal and run the following command:

npx create-react-app ethers-react-app

This command creates a new React project named “ethers-react-app.” After the installation completes, navigate to the project directory:

cd ethers-react-app

Initializing Ethers.js in React

Now that we have our React project set up, let’s initialize Ethers.js. In the project directory, open the src/App.js file and replace the existing code with the following:

import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';

function App() {
const [provider, setProvider] = useState(null);

useEffect(() => {
const initializeProvider = async () => {
if (window.ethereum) {
await window.ethereum.request({ method: 'eth_requestAccounts' });
const provider = new ethers.providers.Web3Provider(window.ethereum);
setProvider(provider);
}
};

initializeProvider();
}, []);

return (
<div>
<h1>Ethers.js and React Integration</h1>
{/* Your application code goes here */}
</div>
);
}

export default App;

In the above code, we import the ethers module from Ethers.js and initialize a React component called App. The useEffect hook is used to initialize the Ethers.js provider when the component mounts. The provider is created using new ethers.providers.Web3Provider(window.ethereum). The window.ethereum object is injected by MetaMask or any other Ethereum wallet that supports the Ethereum Provider API.

Connecting to an Ethereum Network

To interact with an Ethereum network, we need to connect our Ethers.js provider to a specific network. We can achieve this by updating our App component with a network connection functionality. Modify the App component code as follows:

function App() {
// ...

const [network, setNetwork] = useState('');

useEffect(() => {
// ...

const getNetwork = async () => {
if (provider) {
const network = await provider.getNetwork();
setNetwork(network.name);
}
};

getNetwork();
}, [provider]);

// ...

return (
<div>
<h1>Ethers.js and React Integration</h1>
<p>Connected to network: {network}</p>
{/* Your application code goes here */}
</div>
);
}

In the above code, we define a new state variable network to store the connected network name. The useEffect hook is updated to fetch the current network using the provider.getNetwork() method. The network name is then displayed in the component.

Interacting with Smart Contracts

One of the core functionalities of Ethers.js is its ability to interact with smart contracts on the Ethereum network. To demonstrate this, let’s write a simple contract interaction function. Update the App component code as follows:

function App() {
// ...

const [contract, setContract] = useState(null);

useEffect(() => {
// ...

const deployContract = async () => {
if (provider) {
const signer = provider.getSigner();
const ContractFactory = new ethers.ContractFactory(ABI, Bytecode, signer);
const deployedContract = await ContractFactory.deploy();
await deployedContract.deployed();
setContract(deployedContract);
}
};

deployContract();
}, [provider]);

// ...

const interactWithContract = async () => {
if (contract) {
const result = await contract.someFunction();
console.log(result);
}
};

return (
<div>
{/* ... */}
<button onClick={interactWithContract}>Interact with Contract</button>
{/* ... */}
</div>
);
}

In the above code, we define a new state variable contract to store the deployed contract instance. The deployContract function is used to deploy a contract using the ethers.ContractFactory class. Replace ABI and Bytecode with the actual ABI and bytecode of your contract. Once the contract is deployed, we store it in the contract state variable.

The interactWithContract function demonstrates a basic contract interaction. In this example, we assume that the contract has a function named someFunction. When the "Interact with Contract" button is clicked, the function is invoked, and the result is logged to the console.

Listening for Contract Events

Listening for contract events is an important aspect of DApp development. Ethers.js provides an elegant way to subscribe to contract events and react to them. Update the App component code as follows:

function App() {
// ...

const [events, setEvents] = useState([]);

useEffect(() => {
// ...

const subscribeToEvents = async () => {
if (contract) {
contract.on('EventName', (arg1, arg2) => {
setEvents((prevEvents) => [...prevEvents, { arg1, arg2 }]);
});
}
};

subscribeToEvents();

return () => {
if (contract) {
contract.removeAllListeners();
}
};
}, [contract]);

// ...

return (
<div>
{/* ... */}
<ul>
{events.map((event, index) => (
<li key={index}>
{event.arg1} - {event.arg2}
</li>
))}
</ul>
{/* ... */}
</div>
);
}

In this code, we define a new state variable events to store the contract events. The useEffect hook is updated to subscribe to the event named 'EventName' using the contract.on method. Replace 'EventName' with the actual name of the event you want to listen to. When an event is emitted, the event arguments are collected and stored in the events state variable.

We also include a cleanup function in the useEffect hook's return statement to remove all event listeners when the component unmounts.

Handling Transactions and Signatures

When interacting with Ethereum, handling transactions and signatures is crucial. Ethers.js simplifies this process by providing built-in functions and utilities. Update the App component code as follows:

function App() {
// ...

const [transactionHash, setTransactionHash] = useState('');

// ...

const sendTransaction = async () => {
if (contract) {
const signer = provider.getSigner();
const transaction = await signer.sendTransaction({
to: '0x...',
value: ethers.utils.parseEther('0.1'),
});
setTransactionHash(transaction.hash);
}
};

// ...

return (
<div>
{/* ... */}
<button onClick={sendTransaction}>Send Transaction</button>
{transactionHash && (
<p>
Transaction Hash: <a href={`https://etherscan.io/tx/${transactionHash}`}>{transactionHash}</a>
</p>
)}
{/* ... */}
</div>
);
}

In this code, the sendTransaction function sends a transaction from the connected Ethereum account to the specified recipient address. Replace '0x...' with the actual recipient address. We also specify the transaction value using ethers.utils.parseEther to convert Ether denominations.

The resulting transaction hash is stored in the transactionHash state variable and displayed as a link to Etherscan.

Conclusion

In this article, we have explored the process of integrating Ethers.js with React to build decentralized applications on the Ethereum network. We covered essential concepts such as initializing Ethers.js, connecting to an Ethereum network, interacting with smart contracts, listening for contract events, and handling transactions and signatures.

With the knowledge gained from this article, you are now equipped to embark on your own DApp development journey using Ethers.js and React. Remember to refer to the official documentation and explore additional resources to deepen your knowledge and discover the full potential of these powerful tools.

Happy coding and building your next innovative decentralized application!

--

--

Williams Peter
Coinmonks

Ex-CEO at Kosmero | FullStack Engineer (MERN) | Web2 | Web3 Frontend Engineer | Technical Writer | Developer Relations