React Typescript & Ethers.js Tutorial

0xNotes
5 min readMay 23, 2022

--

Oi Stranger, whatcha devvin?

So you want to use React, TypeScript, and Ethers.js together. Wise decision Stranger.

I have a few assumptions.

  1. A Dev Environment has been set up
    IDE, Compiler etc.
  2. NPM is installed
  3. Basic Understanding: React
  4. Basic Understanding: TypeScript

The end product should look like this. This is not an exhaustive seminar but a simple implementation in as practical of a setting as possible. You might learn some fast TypeScript skills too!

Installing & Cleaning React

Navigate to wherever you’d like this program to live. This command will initialize your project at a basic level. Of course feel free to rename my-app to whatever you choose.

npx create-react-app my-app --template typescript

Upon opening this folder you should be greeted with something like this:

A fancy fresh brand new React application.

/src is bloated

Delete:

App.test.tsx

logo.svg

Clear The Contents Of:

App.tsx

App.css

Setting Some CSS:

App.css

body {background-image: linear-gradient(to right, #a8caba 0%, #5d4157 100%);}.App{height: 100vh;display: flex;}.Container{justify-content: center;align-items: center;display: flex;width: 100%;color: white;font-size: 28px;font-weight: 600;}

This will handle the background as well as the app layout. We also define a container for text.

Building A Component:

Now that we have cleared and deleted some files its time to actually build stuff. Most tutorials will have you create all this stuff in App.tsx

In the real world we don’t have that luxury nor would we want it. Proper encapsulation will make your code more readable.

Create:

Folder: /src/components

Folder: /src/components/NavBar

File: /src/components/index.tsx

File: /src/components/NavBar.css

Should look like this after creating those folders/files.

index.tsx

Take note of how we are defining a props interface. States should live at the topmost level they can in a React project. All of the code that handles the wallet connection will be passed from App.tsx to index.tsx

Apologies for how medium handles code formatting.

import "./NavBar.css"type Props = {connectWalletHandler: any;buttonText: string;}export default function NavBar({ connectWalletHandler, buttonText }: Props) {return (<div className="NavBar"><div className="CustomButton" onClick={connectWalletHandler}> {buttonText}</div></div>);}
Filled out index.tsx

NavBar.css

Take note of the hex in background-color, you have 2 more digits you can use to assign opacity!

.NavBar{background-color: #00000098;height: 100vh;width: 200px;display: flex;align-items: flex-end;justify-content: center;color: white;}.CustomButton{padding: 0.75rem;margin-bottom: 2rem;border: 2px solid white;cursor: pointer;}
Filled NavBar.css

Installing Ethers:

npm i --save ethers
Getting close!

Back to App.tsx:

We are at the final step of this tutorial. There will be more explained below about what’s actually happening and what I think is prescient to understand.

App.tsx

import React, { useState } from 'react';import './App.css';import NavBar from './components/NavBar';function App() {const [buttonText, setButtonText] = useState('Connect Wallet');const [defaultAccount, setDefaultAccount] = useState(null);const [errorMessage, setErrorMessage] = useState("");const connectWalletHandler = () => {if ((window as any).ethereum) {(window as any).ethereum.request({ method: 'eth_requestAccounts' }).then((result: any) => {//Provides a list of connected eth walletsaccountChangedHandler(result[0]);setButtonText('Wallet Connected');})} else {setErrorMessage("Please Install A Wallet!");}}
const accountChangedHandler = (newAccount: React.SetStateAction<null>) => {setDefaultAccount(newAccount);}
return (<div className="App"><NavBarconnectWalletHandler={connectWalletHandler}buttonText={buttonText} />
{defaultAccount ?(<div className='Container'>Welcome {defaultAccount}</div>):(<div className='Container'>No Wallet Connected</div>)}</div>);}export default App;

Most IDE’s have a built in code formatter. CTRL + SHIFT + I will format a document in VSCode.

Our completed app, there’s a lot going on here.

Run Page:

npm start 
Works on my machine.

What just happened?

The connectWalletHandler is passed to the navbar, take special note of the syntax on line 12.

if((window as any).ethereum)

Typescript hates certain aspects of this, there are ways to tell the compiler that .ethereum can exist on window so you can type something simple like window.ethereum This solution works for now however.

When connectWalletHandler() is executed it first looks to see if a web3 interface is present on the users browser. If so it will then request to connect with the first account available and then pass that to accountChangedHandler()

This is the most simple setup we can do, after this you should be able to implement other features such as sending transactions to contracts. It wont be too different, just don’t forget your handy (as any) trick.

One last thing that’s worthy of explaining is what happens on line 34. This is called a ternary operator. {someValue? (<div>True</div>):(<div>False</div>)} would be a simple example of how this works. If someValue is true then the html in the first parentheses is rendered, else the second is. This is a useful simple tool to handle conditional rendering!

Github: https://github.com/0xNotes/ethers-react-ts-tutorial

Thanks for reading, I know it’s a bit rough around the edges but it should be helpful!

-0xNotes

--

--