ReactJS - Character Selection
Tags: react, webdev, programming, mit
Published: 2024-03-01 23:13:50

Test out: https://kylestech95.github.io/tile-selection-tool-interactive
Source Code: https://github.com/KylesTech95/tile-selection-tool-interactive
Clone Ref: https://github.com/KylesTech95/tile-selection-tool-interactive.git

As a gamer it is essential to navigate through options & characters. You can do exactly that with this traditional selection-feature created with ReactJS, CSS, & HTML.

Users can navigate through characters with their mouse or keypad:

## **Controls**:

- Mouse move/hover
- > Right Arrow
- < Left Arrow
- v Down Arrow
- ^ Up Arrow

## Instructions
![Instructions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odqobh7dujx9n9ji391t.gif)

## Languages: 
1. ReactJS
2. CSS
3. JavaScript
4. HTML

## Learning Objectives from project-code
1. Understanding of project setup
2. Mapping data with _**key** index_
3. Understanding a few basic [<u>ReactJS-Hooks</u>](https://legacy.reactjs.org/docs/hooks-intro.html):

- `a. useState()`
- `d. useRef()`

## Project Setup
While there are a number of ways to setup a tile-selection program,
this project utilizes an **_array of objects_**, stored into a state called _**player**_, and then rendered into 6 list-items `<li className="list-item"></li>` in the _**domain(DOM)**_.

![character selection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j69rgiqwyw7sat5y5t8z.gif)

**Tile Tracking**
Within _App.js_, take a look at the **_player_** Array.
Each object listed contains a `src:` property with an array of 2 numbers representing **x** & **y**, respectively.
After iterating through the array, each player `src:` is parsed into objects and used for tracking tiles in the DOM.

Within _choice.js_, un-comment the code below and press any _**arrow key**_ to view the output:
`// fn converts array to object with 2 arguments (element,index)
  const arrayToObject = (p,index) =>{
    return {x:p[index].pos[0],y:p[index].pos[1]}
   }
`
`const items = document.querySelectorAll('.list-item')
`
`for(let i = 0; i < items.length; i++){
        // convery array to an object
        let obj = arrayToObject(player,i)
        // console.log(obj)
        // console.log(items[i])
        // console.log("\n")
}
`

![position coords](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhiogjszuwab3uogvh4q.png)

## ReactJS Key
Stay on _choice.js_ and navigate to `// return render`. Here, 
 **_player_**, or the **_array of objects_**, is being mapped to list all lite-items `<li><li/>` by its key property `key={p.key}`.
Typically a key is required if multiple objects/arrays within a list are being rendered.
The main purpose of keys is to determine which elements have been modified (modify,delete).
View the code below for a better understanding.

`{[...player].map((p,index)=>{
              return (
                <div key={p.key} className="button-back">
                  <li key={p.key} className={`list-item p${index+1}`}><img className="img" src={p.src} alt={p.alt} /></li>
                </div>
              )
            })}
`
Test out: https://kylestech95.github.io/tile-selection-tool-interactive
Source Code: https://github.com/KylesTech95/tile-selection-tool-interactive
Clone Ref: https://github.com/KylesTech95/tile-selection-tool-interactive.git

## hooks
Think of react hooks as an individual who is **_asthmatic_** & holds onto an **_inhaler_** to sustain life, or the <u>_life-cycle_</u>.

<u>You, the developer have asthma and need to ensure your quality of life is functional.</u>
**Do I only have to use my inhaler**? ... **NO**

In addition, you can:

- **_Exercise_** to increase your stamina
- Sustain a **_healthy diet_**
- **Sip on Tea** Fennel Tea, Licorice Tea, Ginger Tea, etc...

Basically, whatever you need to do to maintain asthma may come in the form of the above bulletins.
Similarly, ReactJS uses _hooks_ such as **useState() and useRef**.

**useState Example**
Within `App.js`, we declare a useState() with a string and store it in a variable called **header**.
<u>Now we can use this **state**, or _"life-sustainer"_ inside of a functional component</u>

![usestate1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhyap0dtq7anfyp3it4d.png) 
Within the same file `App.js` scroll down to the bottom of the file.
Within the `<Header/>` component, plug in the **header** variable as a prop.
<u>Just like the _**header**_ prop, I _**carry**_  my _**inhaler**_ wherever I go to prevent asthma attacks or shortness of breath. I need to make living work!</u>

![usestate3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfphov8s1wz4jyllu5jn.png)
Within the same file, scroll to the top to access the `Header` 
 Component.
Plug your prop [header] into the function's arguments and pass it as text in the `<h1>` element.
<u>At this point, we completed a quarter-mile jog.
But wait, in _our current state_ we need to take our _medicine_[inhaler]! The _welcome_ header is displayed.</u>
![usestate2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m28bfqiy7b8ztlosrd8i.png)
Within the same file `App.js` scroll down to the bottom of the file.
Within the `<Choice/>` component, plug in both **header** & **setHeader** variables as a prop.
![usestate3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9v3f4qj188qchegayq8z.png)
Access `choice.js`, navigate the **Choice** component. Plug-in both props [header & setHeader] into the function's arguments.

![choiceusestate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j28a1or0j0keimps8ktz.png)
Finally we set the header's state to the tile's animal-name by accessing it's **_alt_** property when we land on a tile.
<u>Just like both _**header & setHeader**_ props, after I _**use my inhaler**_[header] my breathing, or **_state_** changes. We then set the header to a different state with `setHeader()`. After arriving home, I drank _**ginger tea**_  which changed my state again.</u>
![usestate5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxumldryf46sb036m4mx.png)

For more information on `useState()` learn more with [www3Schools](https://www.w3schools.com/react/react_usestate.asp)

Test out: https://kylestech95.github.io/tile-selection-tool-interactive
Source Code: https://github.com/KylesTech95/tile-selection-tool-interactive
Clone Ref: https://github.com/KylesTech95/tile-selection-tool-interactive.git

**useRef Example**
The `useRef()` hook allows developers to reference elements that do not need to be rendered.

<u>Imagine _**hiring**_ a **_jewel-thief_** to access a secure diamond room by roping down from the roof. Despite evading all of security controls (trip-wires, lasers, cameras,automatic firearms,etc...), the thief keeps their cool. They tactfully grab the diamond and helicopter out from the roof!</u>

<u>The thief is your `useRef()` called `thiefRef`</u>.
_<u>We hire the thief to change the **state** of the jewelry’s position.</u>
<u>The state changes after the thief steals the **diamond** without crashing the application. We summoned our _**ref**_, the application's state changes and no one gets hurt or in trouble...unless you were the jeweler.</u>.

<u>Since you **_hired_** the **_thief_**, and the job was successful, the thief is willing to rob more diamonds for you, in other words the theif,`thiefRef` can be **reused** without being rendered.</u>

**useRef in code**
**Scenario**: _I want_ to access the object **{}** at the top of the screen with the `useRef()` hook
![object brack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mncqqh7alag840keenw.png)
Within `App.js` declare a **useRef()** and store it in a variable called **posRef**.
![p1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h4n7sux5fk9l171imk7f.png)
Just like states, **carry** the **posRef** down to a component, in this case, we **carry** **posRef** down to the `<Object/>` component.
![p2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/273z7zu47bn1kz3ddpb8.png)
Within the same file, scroll to the top of the page, locate the **Object** function, and plug-in posRef into the argument.
![p3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osu02oul1q5r5yy1fhpe.png)
Next, we plant our **posRef** into an html attribute called "_ref_".
![p4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4ljvzpjzfmu1niuuq5c.png)

Finally, we access **posRef** with `posRef.current` which gives us access to the element where the `id="object-container"`.
In the below code, we are removing the value's class, _obj-remove_ with **posRef.current**. How cool is that!
![removeobj](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q8b7mqagf7texzwkg5vp.png)
For more information on `useRef()` learn more with [www3Schools](https://www.w3schools.com/react/react_useref.asp)

In conclusion, 
working with the ReactJS Framework takes time and patience in order to understand how state works as well as the hooks that come with ReactJS.
May this blog post help broaden your understanding of the ReactJS Framework.

Test out: https://kylestech95.github.io/tile-selection-tool-interactive
Source Code: https://github.com/KylesTech95/tile-selection-tool-interactive
Clone Ref: https://github.com/KylesTech95/tile-selection-tool-interactive.git