Search code examples
reactjskeyboardcustom-keyboard

Trying to port web page project to React (web)


I am incredibly new to React but I could not find this answer anywhere (I have seen a lot of examples using React-native but this is for web viewing on PC). I have a really simple page/app that runs using HTML, CSS, JS currently and allows the user to press keys on a keypad (which are mapped as buttons) to guess a word. Trying to rewrite this for React is proving pretty daunting and I was wondering if:

A) This is something that someone else has already done? B) If someone has pointers on how to translate this over into a React component as I cannot find any information on this that is not directly related to importing react-native libraries?

My JS in the simple web view (HTML, CSS, JS) looks like this:

function generateButtons() {
        /*
            alphabet str is split into individual letters with split()
            each letter is mapped with a function .map(letter => ...)
                buttonsHTML write all letters as <button> elements within
                the .html file and creates an onClick event listener that 
                calls handleGuess() function
        */

        let buttonsHTML = 'abcdefghijklmnopqrstuvwxyz'.split('').map(letter =>
            `
                <button
                class="keys"
                id='` + letter + `'
                onClick="handleGuess('` + letter + `')"
                >
                ` + letter + `
                </button>
            `).join('');

        // assigns the value of html id keyboard to buttonsHTML 
        document.getElementById('keyboard').innerHTML = buttonsHTML;
    }

And my incredibly barebones React app currently looks like this (App.js):

import './App.css';
import React from 'react';


function GameTitle() {
  return (
    <h1>Random Word Guessing Game</h1>
  )
}

function GamePrompt() {
  return (
    <p>Word to be guessed:</p>
  )
}

function SetDifficulty() {
  return (
    <label>
      Set difficulty level:
      <select>
        <option value="setEasy">Easy</option>
        <option value="setMedium">Medium</option>
        <option value="setHard">Hard</option>
      </select>
    </label>
  )
}

function GuessCounter() {
  return(
    <p>Number of guesses: </p>
  )
}


const alphabet = [
  "A", "B", "C", "D", "E", "F", "G", "H", "I",
  "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  "S", "T", "U", "V", "W", "X", "Y", "Z"
];

function GameKeyboard() {
  return(
    <>
    {alphabet}
    </>
  )
}

function App () {
  return (
      <div>
        <>
          <GameTitle />
          <GamePrompt />
        </>
        <SetDifficulty />
        <GuessCounter />
        <GameKeyboard />
      </div>
      
  );
}


export default App;

I have tried re-creating an alphabet set-up (using const and displaying it) but when I try to implement a button component mapped to the alphabet elements I have not been able to figure out the correct syntax to allow it to be used as a component.


Solution

  • I think what you need is to use map() in the JSX. In this example the handleGuess() function is passed into the <AlphabetButtons> component by it's parent, but you could put it directly inside <AlphabetButtons> if you wanted to.

    function AlphabetButtons({ handeGuess }) {
      return (
        <div>
          {alphabet.map((letter) => (
            <button
              onClick={() => {
                handeGuess(letter);
              }}
            >
              {letter}
            </button>
          ))}
        </div>
      );
    }
    

    See here for a working example codesandbox.io