如何在 React 中显示分值?

How to show score value in React?

我正在构建一个 rock/paper/scissors React 应用程序,但是当我尝试在我的组件中显示分数值时遇到问题。该应用程序运行良好,但如果用户获胜,我想增加 +1 的分数,如果 CPU 获胜,我想减少 -1,并相应地更新 UI。我在找到通过我的组件传递数据的正确方法时遇到问题。

你能帮我解决这个问题吗?

非常感谢!

App.js

import React from "react"
import Header from "./components/Header"
import Main from "./components/Main"
import Footer from "./components/Footer"

import './App.css';

class App extends React.Component {
  constructor(){
    super()
    this.state = {
      score: 12
    }
    this.setScore = this.setScore.bind(this)
  }

  setScore() {
    this.setState((prevState) => {
      return {
        score: prevState.score + 1
      }
    })
  }

  render() {
    return (
      <div className="App">
        <div className="container">
          <Header 
              rock = "ROCK" 
              paper = "PAPER" 
              scissors = "SCISSORS" 
              score = {this.state.score} 
          />
          <Main setScore = {this.setScore}/>
          <Footer />
        </div>
      </div>
    )
  }
}

export default App;

Header.js

import React from 'react';
import Score from './Score';

import './Header.css';

function Header(props) {
  return (
    <div className="nav-container">
      <div className="title-container">
        <h1 className="no-margin">
          {props.rock} <br></br>
          {props.paper} <br></br>
          {props.scissors}
        </h1>
      </div>
      <div className="score-container">
        <Score />
      </div>
    </div>
  );
}

export default Header;

Score.js

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

class Score extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      score: 0,
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange() {
    this.setState((prevState) => {
      return {
        score: prevState.score + 1,
      };
    });
  }

  render() {
    return (
      <div>
        <div className="score-text">SCORE</div>
        <div className="score-value">{this.state.score}</div>
      </div>
    );
  }
}

export default Score;

Main.js

import React from "react"
import Choice from "./Choice"
import TryAgain from "./TryAgain"

import paper from '../images/icon-paper.svg'
import rock from '../images/icon-rock.svg'
import scissors from '../images/icon-scissors.svg'

import './Main.css';

class Main extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            onScreen: true,
            choiceName: '',
            choiceImage: '',
            choiceBorderColor: '',
            choiceExtraBorderColor: '',
            houseChoice: '',
            results:'',
            score: 0,
            setScore: props.setScore
        }
        this.handleClick = this.handleClick.bind(this)
        this.handleTryAgainClick = this.handleTryAgainClick.bind(this)
    }

    /*function that handles the user choice*/
    handleClick = (choiceName, choiceImage, choiceBorderColor, choiceExtraBorderColor) => () => {
        this.setState({
            onScreen: false,
            choiceName,
            choiceImage,
            choiceBorderColor,
            choiceExtraBorderColor,
        })

        /*function that get a random number between 0 and 2, and set this number to the house index*/
        function getRandomInt(max) {
            return Math.floor(Math.random() * Math.floor(max));
        }

        const index = getRandomInt(3)

        this.setState({
            houseChoice: index
        })

        const results = this.getResults(choiceName, index).toUpperCase()
        this.setState({
            results: results,
        })

        if(results === "WIN") { /*what to put here*/
            const res = this.props.setScore
            console.log(res)
            return {
                res
            }
            console.log(this.state.score) 
            /*
            this.setState((prevState) => {
                return {
                    score: prevState.score + 1 
                }
            })*/
        } else if (results === "LOSE" && this.state.score > 0) {
            console.log(this.state.score)
            this.setState((prevState) => {
                return {
                    score: prevState.score - 1
                }
            })
        }
        else {
            console.log(this.state.score)
            this.setState((prevState) => {
                return {
                    score: prevState.score
                }
            })
        }
    }

    /*function that get the main logic and the results of the game*/
    getResults(choiceName, houseChoice) {
        if(choiceName === "paper" && houseChoice === 0) {
            return "draw"
        } else if(choiceName === "paper" && houseChoice === 1) {
            return "lose"
        } else if(choiceName === "paper" && houseChoice === 2) {
            return "win"
        }
        if(choiceName === "rock" && houseChoice === 0) {
            return "lose"
        } else if(choiceName === "rock" && houseChoice === 1) {
            return "win"
        } else if(choiceName === "rock" && houseChoice === 2) {
            return "draw"
        }
        if(choiceName === "scissors" && houseChoice === 0) {
            return "win"
        } else if(choiceName === "scissors" && houseChoice === 1) {
            return "draw"
        } else if(choiceName === "scissors" && houseChoice === 2) {
            return "lose"
        }
    }

    /*function that switches the screen and resets the index of the house*/
    handleTryAgainClick() {
        this.setState({
            onScreen: true,
            houseChoice: ''
        })
    }
    
    render() {
        return(
            <div>
                {/*HOME PAGE*/}
                <div className="main-container" style={{display: (this.state.onScreen ? "block" : "none")}}>
                    <div className="triangle-container">
                        <div onClick={this.handleClick}>
                            <Choice
                                name="paper"
                                image={paper} 
                                borderColor="hsl(230, 89%, 62%)" 
                                extraBorderColor="hsl(230, 89%, 65%)"
                                handleClick={this.handleClick}
                            />
                        </div>
                        <div onClick={this.handleClick}>
                            <Choice
                                name="scissors"
                                image={scissors} 
                                borderColor="hsl(39, 89%, 49%)" 
                                extraBorderColor="hsl(40, 84%, 53%)"
                                handleClick={this.handleClick}
                            />
                        </div>
                        <div style={{gridArea: "bottom"}} onClick={this.handleClick}>
                            <Choice 
                                name="rock"
                                image={rock} 
                                borderColor="hsl(349, 71%, 52%)" 
                                extraBorderColor="hsl(349, 70%, 56%)"
                                handleClick={this.handleClick}
                            />
                        </div>    
                    </div>
                </div>

                {/*RESULT PAGE*/}
                <div className="result-wrapper" style={{display: (!this.state.onScreen ? "grid" : "none")}}>

                    <div className="user-result-box">
                        <h4 className="result-title">YOU PICKED</h4>
                        <div 
                            className="elem-container result-container"
                            style={{
                                borderColor: this.state.choiceBorderColor, 
                                color: this.state.choiceExtraBorderColor
                            }}
                        >
                            <img src={this.state.choiceImage} className="choice-image" alt="img" />
                        </div>
                    </div>

                    <div className="house-result-box">
                        <h4 className="result-title">THE HOUSE PICKED</h4>

                        {this.state.houseChoice === 0 ? (

                            /*1*/
                            <div 
                                className="elem-container result-container"
                                style={{ 
                                    borderColor:"hsl(230, 89%, 62%)",
                                    color:"hsl(230, 89%, 65%)" 
                                }}
                            >
                                <img src={paper} className="choice-image" alt="img" />
                            </div>

                        ) : ( 

                            this.state.houseChoice === 1 ? (
                            
                            /*2*/
                            <div 
                                className="elem-container result-container"
                                style={{ 
                                    borderColor:"hsl(39, 89%, 49%)", 
                                    color:"hsl(40, 84%, 53%)" 
                                }}
                            >
                                <img src={scissors} className="choice-image" alt="img" />
                            </div>

                        ) : (

                            /*3*/
                            <div 
                                className="elem-container result-container"
                                    style={{ 
                                        borderColor:"hsl(349, 71%, 52%)", 
                                        color:"hsl(349, 70%, 56%)" 
                                    }}
                            >
                                <img src={rock} className="choice-image" alt="img" />
                            </div>
                        ))
                        }

                    </div>
                    <div className="final-result-container">
                    <h1 className="bold">YOU {this.state.results}</h1>
                        <TryAgain onClick={this.handleTryAgainClick}/>
                    </div>
                </div>
            </div>

        )
    }
}

export default Main

在您的 Main.js 文件中,您没有调用 setScore 函数。 你必须用 ().

来调用它
if(results === "WIN") { 
    this.props.setScore()
    /* Remove this unnecessary code.
    console.log(res)
    return {
        res
    } */
}

当您调用 this.props.setScore() 时,它将调用 App.js 中的函数并为您更新分数。然后,App.js 也会自动将更新后的 score 传递给 Score.js 组件。

P.S:请使用codesandbox 或codepen 等在线编辑器来演示工作代码。否则滚动代码很难调试。