我正在构建一个石头/纸/剪刀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
score
应该是道具或状态中的成员,而不是两者,但在Main
中,您将其视为两者。
-
如果
score
应由Main
的父级管理,那么它应该是父级传递给Main
的道具。 -
如果
score
应该由Main
管理(这在我看来是正确的(,那么它应该是Main
状态的成员,而不是作为道具传递给它。
Props是由父级维护的状态信息。状态是由组件自身维护的状态。