导入外部 JavaScript 到 React(通过文件)

huangapple go评论66阅读模式
英文:

Importing External JavaScript Into React (via file)

问题

// 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 display the current state of the word to the 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 the wrong guess to the array
    guessed.indexOf(chosenLetter) === -1 ? guessed.push(chosenLetter) : null;
    // disable the button display
    document.getElementById(chosenLetter).setAttribute('disabled', true);
    // if the answer was correct, reveal the letter in the display and check if the game is won
    if (answer.indexOf(chosenLetter) >= 0) {
        guessedWord();
        checkIfGameWon();
    // incorrect guess, increment the wrong guess count, update mistakes on display, check if the game is over
    } else if (answer.indexOf(chosenLetter) === -1) {
        mistakes++;
        updateMistakes();
        checkIfGameLost();
    }
}

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

/**
 * function determines if the game has been lost by
 * checking the number of mistakes against the
 * allowed max for the user difficulty setting
 * if lost, display a 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 an array to store all individual letters
    wordStatus = answer.split('').map(letter => (guessed.indexOf(letter) >= 0 ? letter : " _ ")).join(''); 
    // maps letters against the answer and reveals the answer when correct letters are passed in
    // returns the element to display to the HTML id wordSpotlight
    document.getElementById('wordSpotlight').innerHTML = wordStatus;
}

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

/**
 * function generates the keyboard buttons
 */
function generateButtons() {
    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 the value of mistakes
    guessed = [];                       // resets the 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 the drop-down menu
}

/**
 * function makes calls (similar to restart())
 * that updates the length of words that are
 * displayed to the 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() function
    guessed = [];                   // same as in restart() function
    randomWord(diff_setting);       // calls the randomWord() function with the default diff setting
    guessedWord();                  // same as in restart() function
    updateMistakes();               // same as in restart() function
    generateButtons();              // same as in restart() function
    guessDifficulty(difficulty);    // gets and returns the drop-down difficulty setting
}

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

/**
 * function assigns the maxWrong value based
 * on user input in the 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 the value to the 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 the user's 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 a value 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 a value 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 a value hard_words: hard_game = hard_words (array)

    if(difficulty == '

<details>
<summary>英文:</summary>

UPDATE: on further review and tinkering, I am thinking a better question is &quot;How to transform JS expressions/logic into React components and props?&quot; Looking at a large array of React examples, I do not think that my JS functions are going to port over well, so I guess I am looking for some pointers on how to handle things better. I have a feeling that breaking several of the JS functions into smaller pieces may be part of the answer, but am having difficulty parsing out what will and won&#39;t work.

I have a simple HTML, CSS, and JS app/page Word Guessing Game that I am attempting to port over to a React web app. I am having trouble understanding how one can import elements into the React components (similar to how I have done it with HTML) to be used by the app.

The way my JS file, `appLogic.JS`, currently looks is as follows:


/*
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 =>

    &lt;button
    class=&quot;keys&quot;
    id=&#39;
    + letter + &#39;
    onClick=&quot;handleGuess(&#39;
    + letter + &#39;)&quot;
    &gt;
    + letter +
    &lt;/button&gt;
    ).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
    }

I have tried to implement the JS from the file by adding it to my index.html file as a &lt;script&gt; element and then tried to reference the JS directly from within my App.js in the React app, however when I do this I do not appear to have access to the variables from within my App.js file to implement them. I tried to import the JS directly in to my App.js file and receive an error that it cannot resolve the path to the file. For reference, the way I am importing the file is as follows into my App.js file:

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 />

    &lt;GameKeyboard handleGuess={handleGuess} /&gt;
&lt;&gt;
&lt;br&gt;&lt;/br&gt;
&lt;RestartButton /&gt;
&lt;/&gt;
&lt;/div&gt;

);
}

This seems like it should be easy for me to figure out, but I have so far not been able to get any helpful error hints and have not found any similar searches that give me enough to go on since this is my first time trying to work with React.
</details>
# 答案1
**得分**: 1
以下是已翻译的内容:
第一步是替换使用普通变量和原生DOM API的命令式代码为声明式JSX代码和状态变量。
例如:
```jsx
// => 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.*方法/属性应该用React和JSX代码替代。您还可以使用useRef钩子来访问DOM元素,以使用React API。

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

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

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

理想情况下,这些函数应该重构为函数,或者至少使用React状态和JSX,而不是document.* API和普通变量。

总的来说,我建议您花更多时间学习和尝试理解React的逻辑,了解组件、属性和状态的工作方式,并进入与普通JS和原生DOM API不同的思维方式。

一旦您对React的逻辑有了很好的理解,尝试逐步将代码重构为React,而不是一次性全部重构。

为了将普通的JS/HTML应用程序转换为React,有很多需要重构的地方,但我认为上面的提示是一个良好的起点,可能会帮助您在学习React的过程中前进。

英文:

The first step you have to take is to replace the imperative code
that uses plain variables and the native DOM API to declarative JSX
code and state variables.

For example:

//=&gt; JS:
let maxWrong = 10;

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

//=&gt; JS:
maxWrong = 10;

//=&gt; React:
setMaxWrong(10);

//=&gt; JS + DOM:
document.getElementById(&#39;maxWrong&#39;).innerHTML = maxWrong;

//=&gt; React + JSX:
&lt;div&gt;{ maxWrong }&lt;/div&gt;

All the document.* methods/properties should be replaced with React and JSX code. You can also check the useRef hook in order to be able to access DOM elements using the React API.

Also, you will need to export the functions from the appLogic.js files and import them using the following syntax:

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

// App.js:
import { handleGuess, checkIfGameWon } from &#39;./assets/js/appLogic.js&#39;;

Ideally, these functions should be refactored to become pure functions or at least use React state and JSX instead of the document.* API and normal variables.

In general, I would suggest that you spend more time to study and try to understand the logic behind React, how Components, Props and State work and get into that mindset which is a bit different from the normal imperative code that we use with plain JS and the native DOM API.

Once you have a good understanding of React's logic, try to refactor your code into React bit by bit, and not all at once.

There quite a few things that need to be refactored in order for the plain JS/HTML app to be converted to React, but I think the tips above are a good start and will probably help you in your journey into React.

huangapple
  • 本文由 发表于 2023年5月17日 10:02:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定