Daniel Eden, Designer

Building a Coin-Tossing Simulator with React, Hooks, and Vercel: Part 1

I’ve never written a React tutorial before—there are plenty of people more qualified than me to do so—but I was recently reading “Why Does the World Exist?” by Jim Holt, which contained a passage that moved me to tinker with an idea:

Think of an infinite sequence of random coin tosses: 1 for “heads,” 0 for “tails.” Even though the sequence as a whole will be patternless, it is guaranteed to contain—by pure chance—all conceivable local patterns. There will be stretches of perfect fullness, consisting of a long run of 1’s. There will be stretches of perfect emptiness, consisting of a long run of 0’s.

Upon reading this, I thought it would be nice to visualise these coin tosses, seeing the longest streaks of heads-versus-tails, as well as how the average ends up over time.

Over a series of a handful of posts, I hope to walk through doing this in a simple React app, making use of React’s hooks, and deploying this little toy on a service called Now, allowing other people to run the simulation on their computers too.

Prerequisites

This post will assume at least a little knowledge about how to use the command line. Nothing terribly complex; navigating between folders with cd, and installing things with npm or yarn.

Which brings me to the other prerequisite: you should make sure you have node and npm installed on your computer. I’m going to be using yarn, an alternative to npm, but for the most part, the two are interchangable:

yarnnpm
yarn add {package}npm install {package}
yarn startnpm start

I’m also assuming you’re a little familiar with HTML, CSS, and JavaScript. You might have written a portfolio website, or tinkered with Neopets, or work closely with developers in your job. If you aren’t familiar with these languages, you might have a little difficulty following the post, but hopefully you can follow along and learn just enough to be dangerous.

Creating a React App

The first step is the simplest one, thanks to a tool called create-react-app. Assuming you have a recent version of node installed, open up the command line, navigate somewhere you’d like your app to live, and run the following command:

npx create-react-app coin-toss

This will create a new folder, coin-toss, and populate it with all the code you need to run an example React application. When the create-react-app command is finished, it will instruct you to do the following:

cd coin-toss
yarn start

Go ahead and do that. You should see that a development server starts running, and your browser should open and take you to a localhost web page, where you see the example React app running.

If you need to stop or restart the development server at any time, you can press Ctrl + C and then run yarn start to begin it again.

Congratulations! Strictly speaking, you’ve just created your first React app! If running the example code has left you a little underwhelmed, don’t fret: next, we’ll start to write some custom code for our application.

The first thing we need to do in our app is have it simulate the basic exercise of tossing a coin. Let’s change our app so that it has a button to toss an imaginary coin and then tells us the result.

Step 1: Removing The Example Code

Open up the coin-toss folder in your code editor of choice (I’m using Visual Studio Code) and you should see the following contents:

node_modules
public
src
↳ App.css
↳ App.js
↳ App.test.js
↳ index.css
↳ index.js
↳ logo.svg
↳ serviceWorker.js
.gitignore
package.json
README.md
yarn.lock

Open up src/App.js. We’re going to delete most of the code already inside it, but feel free to copy-and-paste if it’s easier.

We’ll delete some of the import statements at the top and most of the code in the App function. Here’s what your App.js should look like:

import React from "react"

function App() {
    return <div>The coin toss app will go here!</div>
}

export default App

If the development server is still running, in your web browser you should now see that your app is just a page that says “The coin toss app will go here!”.

Since we deleted the references to logo.svg and App.css in App.js, we can also delete those files:

  node_modules
  public
  src
- ↳ App.css
  ↳ App.js
  ↳ App.test.js
  ↳ index.css
  ↳ index.js
- ↳ logo.svg
  ↳ serviceWorker.js
  .gitignore
  package.json
  README.md
  yarn.lock

Interlude: Understanding React’s JSX Syntax: Let’s go back to App.js for a moment. If you haven’t seen React code before, seeing HTML-like bracketed-code might be a surprise to you:

import React from "react"

function App() {
    return <div>The coin toss app will go here!</div>
}

export default App

This is called JSX syntax, and it’s just a convenient way of writing React code. The line above could also be written like this:

return React.createElement("div", null, "The coin toss app will go here!")

When we write <div> in JSX, it’s telling React to create a div element, without any additional properties or attributes (“props” in React), with “The coin toss app will go here!” as its contents (or “children”).

The create-react-app command, in addition to providing us with some starter code, also enabled us to write JSX syntax so that we didn’t have to write functions like above.


Step 2: Adding The “Toss Coin” Button

Let’s add the “toss coin” button to our app. We can place a button inside the div already in our code. Let’s update the App function like so:

function App() {
    return (
        <div>
            The coin toss app will go here!
            <button>Toss coin</button>
        </div>
    )
}

Save your changes and check the web browser: we now have a button, but clicking it doesn’t do anything yet. Let’s change that:

function App() {
    const tossCoin = () => {
        alert("The coin was tossed")
    }

    return (
        <div>
            The coin toss app will go here!
            <button onClick={tossCoin}>Toss coin</button>
        </div>
    )
}

Now, when you click the button, the browser should show a dialog that says “The coin was tossed”.

In addition to having the tossCoin function, we need to actually have our virtual coin so that we can tell which side it landed on. Like the excerpt from the book at the start of the page, we’ll represent the sides with a 1 for “heads” and a 0 for “tails”.

To manage our coin, we’ll use something called the useState hook. A “hook” in React is just a function that takes advantage of React’s “component lifecycle”, which determines when a component or an app should update.

useState lets us define a variable and provides a function for updating that variable later on. We’ll need one for the coin’s side, and one for the number of times the coin has been tossed.

import React from "react"

const { useState } = React

function App() {
    const [side, setSide] = useState(1)
    const [tossed, setTossed] = useState(0)

    const tossCoin = () => {
        const landedOn = Math.round(Math.random())
        setSide(landedOn)
        setTossed(tossed + 1)
    }

    return (
        <div>
            <p>The coin has been tossed {tossed} times.</p>
            <p>It landed on {side === 1 ? "heads" : "tails"}</p>
            <button onClick={tossCoin}>Toss coin</button>
        </div>
    )
}

export default App

Let’s walk through the changes we just made.

const { useState } = React

This might be unfamiliar syntax again. This is called object destructuring1, and it’s the same as writing:

const useState = React.useState

This code makes the useState hook available in App.js. Next, we update the tossCoin function to use the hook and set some new variables:

const [side, setSide] = useState(1)
const [tossed, setTossed] = useState(0)

This might be new as well! This is another form of destructuring. The useState function returns an array of two values: the state variable, and the function to update the state variable. The first line above can be re-written as:

const result = useState(1)
const side = result[0]
const setSide = result[1]

Looking back to the previous code sample, we’re setting four new variables:

  • side, which will initially be 1
  • setSide
  • tossed, which will initially be 0
  • and setTossed

We’ll use the side and tossed variables to keep track of which side of the coin we see and how many times it’s been tossed, and setSide and setTossed to update them respectively.

Our tossCoin function has been updated too:

const tossCoin = () => {
    const landedOn = Math.round(Math.random())
    setSide(landedOn)
    setTossed(tossed + 1)
}

landedOn is set to either 1 or 0. The Math.random function will return a random floating point number between 0 and 1, so we just take that value and round it to the nearest whole number.

Next, we call the setSide function with our landedOn value to tell our app which side of the coin we see, and setTossed to increase the tossed value by 1.

Finally, the return value of App has been updated to show two paragraphs:

<p>The coin has been tossed {tossed} times.</p>
<p>It landed on {side === 1 ? "heads" : "tails"}</p>

Here, we’re using the tossed variable to indicate how many times we’ve tossed our virtual coin. The curly braces are there to tell React/JSX that we’d like to use a JavaScript variable.

In the next paragraph, we’re checking if the side variable is equal to 1. If it is, we’ll output “heads”, and if it isn’t, we’ll output “tails”.

Putting all of this together, we can now go back to the browser and click the “Toss coin” button, and it will update with the number of times it’s been tossed, along with which side of the coin is seen. If you keep pressing the button, you’ll already start to see some of the patterns mentioned in the excerpt: long sequences of 0’s, followed by long sequences of 1’s, followed by interwoven 0’s and 1’s.

If you’ve made it this far, you should feel proud! We’ve made a React app that responds to user input and dynamically updates.


Part 1 Conclusion: The Power of React: If you’re like me, it’s probably taking (or did take) a while to warm up to the idea of React. Why would I prefer it over regular JavaScript or jQuery? Why does it seem so different from everything else I’ve learned about JavaScript?

Hopefully by following this tutorial you’ve started to feel a little of React’s power come into play. What I’ve found really appealing about React is that it is

declarative and it is reactive.

By declarative, I mean that rather than describing the steps you take to make an element or a variable a certain way, you just describe the element straight away. Let’s look at an example in classic JavaScript:

const button = document.createElement("button")
button.innerHTML = "Toss coin"
button.addEventListener("click", tossCoin)

And compare it to the JSX/React code:

<button onClick={tossCoin}>Toss coin</button>

Especially in larger codebases, writing declarative UI code like this can make managing the codebase much easier.

Secondly, when I say reactive, I’m describing one of the side effects of declarative code, and a feature that React in particular makes available to us.

Notice how in our application, because we’re writing our code declaratively, and we’re letting React handle many of our variables using useState, we don’t have to manually update variables like side or tosses, and we don’t have to change any inner HTML of the paragraph elements of our app. In classic JS, we’d likely have to update a lot of things ourselves:

const firstParagraph = document.createElement("p")
firstParagraph.innerHTML = `The coin has been tossed ${tossed} times.`

// ...much later or elsewhere in our code
tossed = tossed + 1
firstParagraph.innerHTML = `The coin has been tossed ${tossed} times.`

By writing our code declaratively with the help of React, we need only write our paragraph once, and everything updates automatically whenever tossed or other variables change or update.


In the next part of this series, we’ll start to count the total number of times that each side of the coin appears, and visualise them using HTML elements. We’ll also have our coin flipped automatically for us, so that you don’t have to press a button each time.

While waiting for the next post, consider how you might achieve those next steps yourself, or what other creative ways you could use what you’ve learned in this first part.

Thanks for reading, and be sure to follow me on Twitter to find out when the next post is available, and to ask for anything specific you’d like to see in the future posts!

Footnotes

  1. You can learn more about destructuring assignments from the MDN JavaScript documentation