【问题标题】:Score value not incrementing in ReactReact 中的分数不增加
【发布时间】:2020-11-17 17:29:21
【问题描述】:

我正在构建一个石头/纸/剪刀的 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: 0
    }
  }


  render() {
    return (
      <div className="App">
        <div className="container">
          <Header 
              rock = "ROCK" 
              paper = "PAPER" 
              scissors = "SCISSORS" 
              score = {this.state.score} 
          />
          <Main 
              score = {this.state.score}
          />
          <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 score={props.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: props.score
        }
    }

    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: props.score
        }
        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") {
                    this.setState((prevState) => {
                        return {
                            score: prevState.score + 1
                        }
                    })
                }
    }

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

【问题讨论】:

    标签: javascript reactjs components frontend web-deployment


    【解决方案1】:

    score 应该要么是道具状态的成员,而不是两者,但在 Main 中你将其视为两者。

    • 如果 score 应该由 Mainparent 管理,那么它应该是 parent 传递给 Main 的 prop。

    • 如果score 应该由Main 管理(这对我来说似乎是正确的),那么它应该是Main 状态的成员,而不是作为道具传递给它。

    Props 是由父级维护的状态信息。状态是组件自身维护的状态。

    【讨论】:

    • 非常感谢您的回答!是的,我明白了,现在我使用分数作为状态中的
      成员。此外,我有一个函数 ad prop 传递给
      以增加分数,但它不起作用......知道为什么吗?再次非常感谢!
    • @zawrdo - 如果您在将 setter 函数传递给组件时遇到问题,通常的原因是增加过时的值或类似的值。我建议发布一个带有minimal reproducible example 问题的新问题(因为这与上述问题不同),最好是使用堆栈片段([&lt;&gt;] 工具栏按钮)的 runnable 问题。 Stack Snippets 支持 React,包括 JSX; here's how to do one。然后人们可以准确地指出该怎么做。请记住,“最小”和“可复制”的艺术都很重要。 ;-)
    • 好的,再次感谢您!抱歉,我是平台新手。我会按照你的建议去做
    • @zawrdo - 无需道歉! :-) 当你发布它时给我打电话,以防我在附近并且可以提供帮助。
    猜你喜欢
    • 2021-11-13
    • 2020-06-05
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 2020-06-20
    • 2022-12-16
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多