更新:在进一步的回顾和修改中,我认为更好的问题是"如何将JS表达式/逻辑转换为Reaction组件和props ?"查看大量的Reaction示例,我认为我的JS函数不能很好地移植,所以我想我正在寻找一些关于如何更好地处理事情的指针.我有一种感觉,将几个JS函数分解成更小的部分可能是答案的一部分,但我很难解析出哪些可以工作,哪些不能工作.

我有一个简单的HTML,CSS和JS应用程序/页面猜字游戏,我正试图通过一个react 网络应用程序.我很难理解如何将元素导入到应用程序使用的Reaction组件中(类似于我如何使用HTML语言).

我的JS文件appLogic.JS目前的外观如下:

/*
 Notes:
   import random words from CSV using getWords.js
*/

let random_words = ['dog', 'flower', 'piano', 'student', 'chrysanthemum'];


// outer variables 
let answer = '';             // holds the value of the random word to be served to the .html 
let maxWrong = 10;           // default game is set to easy  
let diff_setting = 'Easy';   // default ""
let mistakes = 0;            // mistakes are initialized to 0
let guessed = [];            // guessed letters are stored in an array initialized empty
let wordStatus = null;       // used to dislay current state of word to user (guessedWord())


/**
 * function is called by generateButtons and 
 * handles keyboard button press events
 * on each press
 */
function handleGuess(chosenLetter) {
    // if guessed/pressed letter is false, push wrong guess to array
    guessed.indexOf(chosenLetter) === -1 ? guessed.push(chosenLetter) : null;
    // disable the button display
    document.getElementById(chosenLetter).setAttribute('disabled', true);
    // if answer was correct, reveal the letter in the display and check if game won
    if (answer.indexOf(chosenLetter) >= 0) {
    guessedWord();
    checkIfGameWon();
    // incorrect guess increment wrong guess count, update mistakes on display check if game over
    } else if (answer.indexOf(chosenLetter) === -1) {
    mistakes++;
    updateMistakes();
    checkIfGameLost();
    }
}

/**
 * function determines if game has been won by
 * checking if values in wordStatus are equal to
 *  the letters in answer, game is won
 * If game won, displays a message to the user
 */
function checkIfGameWon() {
    if (wordStatus === answer) {
    document.getElementById('keyboard').innerHTML = 'Good job!';
    }
}

/**
 * function determines if game has been lost by
 * checking the number of mistakes agains the
 * allowed max for the user difficulty setting
 * if lost, displays message to the user
 */
function checkIfGameLost() {
    if (mistakes === maxWrong) {
    document.getElementById('wordSpotlight').innerHTML = 'The answer was: ' + answer;
    document.getElementById('keyboard').innerHTML = 'Better luck next time!';
    }
}

/**
 * function updates the "_" display of the word
 * to map the guessed letters and reveal the answer
 * letters if correctly guessed
 */
function guessedWord() {
    // creates array to store all individual letters
    wordStatus = answer.split('').map(letter => (guessed.indexOf(letter) >= 0 ? letter : " _ ")).join(''); 
    // maps letters against answer and reveals the answer when correct letters passed in
    // returns the element to display to the html id wordSpotlight
    document.getElementById('wordSpotlight').innerHTML = wordStatus;
}

/**
 * function assigns value of mistake to html element mistake
 * (number of wrong guesses)
 */
function updateMistakes() {
document.getElementById('mistakes').innerHTML = mistakes;
}

/**
 * function generates the keyboard buttons
 */
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 
            callse 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;
}

/**
 * function is the process assigned to the button of the same
 * name. It resets the game (new random word) and resets the
 * number of guesses
 */
function restart() {
    let defaultSelection = 'Easy';      // default value passed to setDifficulty
    mistakes = 0;                       // resets value of mistakes
    guessed = [];                       // resets guessed array
    guessedWord();                      // get the word display ("_")
    updateMistakes();                   // put the value of wrong guesses, starts at 0
    generateButtons();                  // create buttons (no longer disabled)
    setDifficulty(defaultSelection);    // get the difficulty setting from drop-down menu
}

/**
 * function makes calls (similar to restart())
 * that updates the length of words that are
 * displayed to user (easy, medium, hard)
 * 
 * this function is called whenever the user
 * changes the value in the drop-down and
 * that value is passed in (difficulty)
 * @param {*} difficulty = str val, user setting  
 */
function setDifficulty(difficulty) {
    diff_setting = difficulty;      // default 'Easy'
    mistakes = 0;                   // same as in restart() f(x)
    guessed = [];                   //same as in restart() f(x)
    randomWord(diff_setting);       // calls the randomWord() f(x) with the default diff setting
    guessedWord();                  // same as in restart() f(x)
    updateMistakes();               // same as in restart() f(x)
    generateButtons();              // same as in restart() f(x)
    guessDifficulty(diff_setting);  // gets and returns the drop-down difficulty setting
}

// These are the initial launch functions
randomWord(diff_setting);            // gets random word w default difficulty 
generateButtons();                   // ""
guessedWord();                       // ""
guessDifficulty(diff_setting);       // ""


/**
 * function assigns maxWrong value based
 * on user input in drop-down menu
 * @param {*} difficulty = str, user selection
 */
function guessDifficulty(difficulty){
    if(difficulty == 'Easy'){               // if easy, return 10 guesses
        maxWrong = 10;
    }else if(difficulty == 'Medium'){       // if medium, 7 guesses
        maxWrong = 7;
    }else if(difficulty == 'Hard'){
        maxWrong = 5;                       // if hard, 5 guesses
    }else{
        maxWrong = 10;                      // else, default                 
    }
    // set value to HTML element
    document.getElementById('maxWrong').innerHTML = maxWrong;
}

/**
 * function returns word length according to user
 * difficulty settings
 * @param {*} difficulty = drop-down menu selection
 * @returns array of lengths corresponding to user selection
 */
function getSelection(difficulty){
    // filter for all words with a length less than 6
    let easy_game = random_words.filter((easy_words) => {
    if(easy_words.length < 6){
        return easy_words;}});  // return as val easy_words: easy_game = easy_words (array)
    // filter for all words with a length of 6-10
    let medium_game = random_words.filter((med_words) => {
    if(med_words.length >= 6 && med_words.length <= 9){
        return med_words;}});   // return as val med_words: medium_game = med_words (array)
    // filter for all words with a length greater than 9
    let hard_game = random_words.filter((hard_words) => {
    if(hard_words.length > 9){
        return hard_words;}});  // return as val hard_words: hard_game = hard_words (array)

    if(difficulty == 'Easy'){           
    return easy_game;                       // if the difficulty was set to easy, return easy array
    } else if (difficulty == 'Medium'){
    return medium_game;                     // if the difficulty was set to medium, return medium array
    } else if (difficulty == 'Hard') {
        return hard_game;                   // if the difficulty was set to hard, return hard array
    } else {
        return easy_game;                   // else return default easy
    }
}

/**
 * function takes in an array and selects a word
 * with a randomizing sequence
 * @param {*} diff = difficulty setting passed in from drop-down
 */
function randomWord(diff) {
    var arr = getSelection(diff);                           // get array according to difficulty
    answer = arr[Math.floor(Math.random() * arr.length)];   // assigns random value from calc index to answer
}

我try 通过将JS作为元素添加到我的index.html文件中来从文件实现JS,然后try 从React应用程序中的App.js中直接引用JS,但是当我这样做时,我似乎无法访问App.js文件中的变量来实现它们.我try 将JS直接导入到我的App.js文件中,但收到一个错误,指出它无法解析该文件的路径.作为参考,我将该文件导入到我的App.js文件的方式如下:

import Button from 'react-bootstrap/Button';
import './App.css';
**import './assets/js/appLogic.js';**
import React from 'react';


// outer variables 
let answer = '';             // holds the value of the random word to be served to the .html 
let maxWrong = 10;           // default game is set to easy  
let diff_setting = 'Easy';   // default ""
let mistakes = 0;            // mistakes are initialized to 0
let guessed = [];            // guessed letters are stored in an array initialized empty
let wordStatus = null;       // used to dislay current state of word to user (guessedWord())


function GameTitle() {
  return (
    <h1 className='game-header'>Random Word Guessing Game</h1>
  )
}

function GamePrompt() {
  return (
    <p className='word-prompt'>Word to be guessed:</p>
  )
}

function SetDifficulty() {
  return (
    <div className='dropdown-content'>
      <label className='difficulty-prompt'>
        Set difficulty level:
        <select className='difficulty-dropdown'>
          <option value="setEasy">Easy</option>
          <option value="setMedium">Medium</option>
          <option value="setHard">Hard</option>
        </select>
      </label>
    </div>
  )
}


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"
];


const handleGuess = (letter) => {
  alert(`${letter} pressed!`);
};

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

function GuessCount() {
  return(
    <div id='guess-counter'>
    </div>
  )
}

function WrongGuessesPrompt() {
  return(
    <span id='mistakes'>{mistakes}</span>
  )
}

function TallyGuessesPrompt() {
  return(
    <span id='maxWrong'>{maxWrong}</span>
  )
}

function WordGuessContainer() {
  return(
    <div className='container'>
      <GuessCount />Guesses: <WrongGuessesPrompt /> of <TallyGuessesPrompt />
    </div>
  )
}

function RestartButton() {
  return(
    <>
      <Button>Restart</Button>
    </>
  )
}

export default function App () {
  return (
      <div>
        <>
        <SetDifficulty />
          <GameTitle />
          <GamePrompt />
        </>
        <WordGuessContainer />

        <GameKeyboard handleGuess={handleGuess} />
        <>
        <br></br>
          <RestartButton />
        </>
      </div>
      
  );
}

这对我来说似乎很容易弄清楚,但到目前为止,我还没有得到任何有用的错误提示,也没有找到任何类似的搜索,因为这是我第一次try 使用Reaction.

推荐答案

您必须采取的第一步是替换命令性代码 它使用普通变量和声明性JSX的本机DOMAPI 代码和状态变量.

例如:

//=> JS:
let maxWrong = 10;

//=> React:
const [ maxWrong, setMaxWrong ] = useState(10);

//=> JS:
maxWrong = 10;

//=> React:
setMaxWrong(10);

//=> JS + DOM:
document.getElementById('maxWrong').innerHTML = maxWrong;

//=> React + JSX:
<div>{ maxWrong }</div>

所有document.*个方法/属性都应该替换为Reaction和JSX代码.您还可以判断useRef挂钩,以便能够使用Reaction API访问DOM元素.

此外,您还需要从appLogic.js个文件中导出函数,并使用以下语法导入它们:

// appLogic.js:
export function handleGuess(chosenLetter) {}
export function checkIfGameWon(){}

// App.js:
import { handleGuess, checkIfGameWon } from './assets/js/appLogic.js';

理想情况下,这些函数应该被重构为pure个函数,或者至少使用REACT STATE和JSX,而不是document.*个API和NORMAL变量.

总的来说,我建议您花更多的时间研究并try 理解Reaction背后的逻辑,组件、props 和State是如何工作的,并进入这种心态,这种心态与我们使用普通JS和本机DOM API所使用的正常命令性代码略有不同.

一旦您对Reaction的逻辑有了很好的理解,就可以try 将您的代码重构为Reaction一点一点,而不是一次全部重构.

有相当多的东西需要重构,才能将普通的JS/HTML应用程序转换为Reaction,但我认为上面的提示是一个很好的开始,可能会帮助您进入Reaction.

Reactjs相关问答推荐

有没有方法覆盖NextJS 14中的布局?

无法在jest中发布行动

TypeError:b不是React.js中的函数错误

如何在react 流中使用文本区域和改变 node 的输入大小?

Reaction中的数据加载不一致

Chart.js如何go 除边框

FabricJS反序列化问题

显示我是否加入聊天应用程序时出现问题

useEffect内部的RETURN语句在首次按钮点击事件中似乎无效的原因是什么?

未处理的拒绝 (TypeError):无法读取未定义的属性(读取协议)

在react 中单击父级中的按钮时如何将数据从子级发送到父级?

如何测试使用 React.createportal 呈现的组件?

使用 map 循环浏览列表列表中的列表并显示它们

为什么刷新页面时我的localStorage PET值变成空字符串?

Select 项目后 Select HeadlessUI 组合框中的所有文本?

带有 webpack 错误多个文件匹配路由名称的 Expo-router.无法Bundle 或部署应用程序

我正在通过 API(有效)从 MongoDB 传递数据.可视化但我不断收到此 TypeError: Cannot convert undefined or null to object

在 React 的父级中多次调用子级时从子级获取数据到父级

意外的标记.您可能需要一个合适的加载器来处理这种文件类型.书?.img? /*#__PURE__*/React.createElement("img",

我想将悬停 colored颜色 更改为红色.写了一个话题,这个元素没有react ,怎么解决呢?