Making Your First Game With React Hooks
Published: 2023-05-24 18:59:25

## I. Overview
In this article I will being going over how to create a simple multiple choice game using React. In this walkthrough we will be creating a 'color guessing game' that can be used to familiarize yourself with the hex values of different colors. Building apps like these are a great way to solidify your understanding on the usage of React hooks as they are foundational in what makes the React framework so powerful!

Take a look at the final product on CodeSandbox [here](https://codesandbox.io/p/github/evanryan210/hex-color-practice-tool/master?file=%2Fsrc%2FApp.test.tsx%3A1%2C1&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522panelType%2522%253A%2522TABS%2522%252C%2522id%2522%253A%2522clhyn99zv000c356ksm08k7y8%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clhyn99zv000c356ksm08k7y8%2522%253A%257B%2522id%2522%253A%2522clhyn99zv000c356ksm08k7y8%2522%252C%2522activeTabId%2522%253A%2522clhyna10y00aq356kdc3cyq8m%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522id%2522%253A%2522clhyn9x7e005x356kxp3j5oob%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522port%2522%253A3000%252C%2522id%2522%253A%2522clhyna10y00aq356kdc3cyq8m%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.test.tsx%2522%252C%2522id%2522%253A%2522clhynb1gs00hg356kh4wta075%2522%252C%2522mode%2522%253A%2522temporary%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D).

---

##II. Setup

Here is the basic HTML that we will use for our app. We will add in the rest later.
```
<div style={{ display: 'flex', flexDirection: 'column' }}>
      <h1 style={{ textAlign: 'center' }}>Pick the Color Value</h1>
      <div className={styles.container}>
        <div style={{ backgroundColor: `${divColor}` }} className={styles.colorBox}>
          <span>{INCORRECT/CORRECT DISPLAY GOES HERE}</span>
        </div>
      </div>
      <div className={styles.buttonContainer}>
        {WHERE MULTIPLE CHOICE OPTIONS GO HERE}
      </div>
      <p style={{ textAlign: 'center' }}>{CORRECT ANSWER COUNT GOES HERE}</p>
      <p style={{ textAlign: 'center' }}>{INCORRECT ANSWER COUNT GOES HERE}</p>
</div>
```

---

##III. Generating values for initial render of our app

Lets start by initializing the random color that will be displayed in our container box. We will do this by using the `'useState'` hook, and giving it an initial value. 

1. Create a function that return 3 random hex values in an array `getRandomHexArray()`. 

```
const getRandomHexArray = () => {
    const value1 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    const value2 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    const value3 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    return [value1, value2, value3]
  }
```
2. Now we want to create a variable `initialRandomArray` that will call the function we just created on each render, so we will have a new random array of hex values every time there is a state change.

`let initialRandomArray = getRandomHexArray();
`

3. We also need a state that holds a random value of range 0-initialRandomArray.length. This will decide which color code is "Correct" for each question. And we will create another state to hold our `initialRandomArray `as well.

const [answerIndex, setAnswerIndex] = useState<number>(Math.floor(Math.random()*3))
const [hexArray, setHexArray] = useState<string[]>(initialRandomArray);

---

##IV. Displaying buttons using map()

```
      <div className={styles.buttonContainer}>
        {WHERE MULTIPLE CHOICE OPTIONS GO HERE}
      </div>
```
Now we will finish this code to properly display our multiple choice options that the user will be clicking on.

```
<div className={styles.buttonContainer}>
        {hexArray.map((button, index) => {
          return (
            <button key={index} className={styles.button} onClick={()=>{handleSubmit(index)}}>{hexArray[index].toUpperCase()}</button>
          )
        })}
```
This code returns a <button> element for every value we have inside `hexArray`. We pass a child to the <button> element of `{hexArray[index].toUpperCase()}` which displays the hex code on each of our buttons. We also pass to our onClick property a arrow function that runs our submission handler function which we will create now.

---

##V. Handling submissions

```
const handleSubmit = (index: any) =>{
    hexArray[index] == hexArray[answerIndex] ? handleCorrect() : handleIncorrect()
    let newRandomArray = getRandomHexArray()
    setHexArray(newRandomArray)
    setAnswerIndex(Math.floor(Math.random() * 3))
    setIsOpen(true)
    setTimeout(()=> setIsOpen(false), 1000)
  }

const handleCorrect = () =>{
    setIsCorrect(true)
  }

  const handleIncorrect = () =>{
    setIsCorrect(false)
  }
```
This function does a few things:

1. It checks to see if the answer was correct by passing on index of the click event and comparing that to the hexArray at the answerIndex variable we store.
2. Generates a new random array `newRandomArray`
3. Sets isOpen to true, which lets us conditionally render feedback for the user to display 'Correct' or 'Incorrect' on each question as shown below.

```
<div style={{ backgroundColor: `${hexArray[answerIndex]}` }} className={styles.colorBox}>
     <span className={styles.colorBoxText}>&nbsp;{isOpen ? isCorrect ? 'Correct!' : 'Incorrect' : ''}</span>
</div>
```
4. The setTimeout allows us to only display the 'Correct/Incorrect' text briefly for 1000 milliseconds by running an arrow function to set our `isOpen` variable back to `false`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bit6zmamkbsepo080o5o.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4uu00wm3tgb17ez1o8a8.png)


####There you go! Your first React game using hooks.


Extra Credit: Add a count for incorrect and correct answers using useRef

---

Author: Evan Ryan
_OrangeSpark Solutions_