如何解决通过.then功能和甜蜜警报传递状态
我正在尝试创建一个游戏,当用户的得分达到5分时会弹出一个模式。当用户错误地回答问题时,将显示答案反馈。我正在使用甜蜜警报来提供答案反馈。
我想要实现的是,单击“查看最终分数”按钮后,我希望用户重定向到页面上方的游戏,在该页面上将显示最终分数。
我一般对反应/编程都是新手,但我尝试了许多无济于事的选项。当前使用的方法给我:
因此,任何帮助或指导将不胜感激:)
export class QuestionModal extends Component {
constructor(props) {
super(props);
this.state ={
questions: {},answerOptions: [],chosenAnswer: '',isAnswerCorrect: false,value: '',answer: '',gameOver: false,gameScore: this.props.context.gameScore,};
this.handleChange = this.handleChange.bind(this);
this.gameOver = this.gameOver.bind(this);
}
// Axios call to get questions from database
componentDidMount() {
axios.get('/hacker')
.then((response) => {
console.log([response.data]);
const result = response.data;
this.setState({
questions: result,answerOptions: result.answerOptions,answer: result.answer,explanation: result.explanation,}); console.log(this.state.answer);
}).catch((error) => {
this.setState({isLoaded: true,error});
});
}
/* This function is invoked when the user hits submit after answering the question. It does 2 things:
1. Compares the answer provided by the user vs the answer in the db. Sweetalert is then used to pop up and show the correct/wrong answer.
2. Invokes the onHide function to hide the question modal
*/
checkAnswer() {
console.log(this.state.gameScore);
if (this.state.answerOptions[this.state.answer] === this.state.value) {
console.log('correct');
swal("Nice one!",this.state.explanation,"success",{
closeOnClickOutside: false,buttons: {
confirm: "Back to the game!"
}
});
} else {
console.log('incorrect');
swal("So close!","error",{
closeOnClickOutside: false,buttons: {
confirm: "View your final score!"
},}).then (function() {
// window.location.href = "./gameover";
this.gameOver();
});
}
this.props.onHide();
}
gameOver() {
console.log (this.state.gameScore)
this.props.history.push({
pathname: `/gameover`,gameScore: this.state.gameScore,});
}
handleChange(event) {
console.log('value is ' + event.target.value);
this.setState({
value: event.target.value,});
}
render() {
return (
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
backdrop="static"
keyboard={false}
>
<Modal.Header>
<Modal.Title className="hackerGameModal"> Answer the question below correctly to continue with the game!</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="hackerGameQuestion">
<h4>{this.state.questions.question}</h4>
<form>
<FormControl component="fieldset" >
<RadioGroup aria-label="quiz" name="hackerGameAnswers" onChange={this.handleChange} value={this.state.value}>
{this.state.answerOptions.map((option) => {
return (
< FormControlLabel key={option} value={option} control={<Radio color="primary"/>} label={option}/>
);
})}
</RadioGroup>
</FormControl>
</form>
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="contained" type="submit" color="primary" onClick={this.checkAnswer.bind(this)}>Submit</Button>
</Modal.Footer>
</Modal>
);
}
}
export default withRouter(QuestionModal);
编辑:checkAnswer()函数中的console.log(this.state.gameScore)显示当前分数。该错误发生在第83行,其中:
.then (function() {
this.gameOver() //this is line 83
但是当调用gameOver()函数时,会出现未定义的错误。
gameOver() {
console.log (this.state.gameScore)
this.props.history.push({
pathname: `/gameover`,});
}
Hacker.js(主要游戏文件,一些功能已删除,因为我认为它与问题无关)
class Hacker extends Component {
constructor(props,context) {
super(props,context);
this.state = {
display: 'none',gameStarted: false,hackerHasBeenHit: false,showChallengeQuestion: false,gameScore: 0,buttonDisplay: 'none',showQuizModal: false,};
}
/* This function is invoked when the user clicks the start button,the interval sets the speed to which the hacker appears */
startGame() {
if (this.state.gameStarted) {
return;
}
this.setState({
gameStarted: true,display: 'block',});
setInterval(() => {
this.showHackers();
},1000);
}
/* This function does 2 things:
1. When the user clicks on the "hacker",the image will change to the shield for a certain period of time
2. Add point to score
*/
countScore(e) {
const target = e.target;
target.parentNode.classList.add('gameShield');
this.setState({
hackerHasBeenHit: true,gameScore: this.state.gameScore + 1,});
window.setTimeout(function() {
target.parentNode.classList.remove('gameShield');
},1000); // This sets the time which the shield is displayed for
this.challengeQuestion();
}
/* This function shows the challenge question every 5 times
+1 is added to challengeScore as gameScore starts from 0. Ensures question does not pop up at 0,6,11,etc
*/
challengeQuestion() {
const challengeScore = this.state.gameScore + 1;
if (challengeScore % 5 === 0) {
this.setState({
showChallengeQuestion: true,showQuizModal: true,});
this.props.history.push({
gameScore: this.state.gameScore,})
};
}
render() {
const addModalClose = () =>
this.setState({
showQuizModal: false,});
return (
<section>
<WebHeader/>
<div className="hackerGameContainer">
<div className="gameStartButton">
<Button variant="contained" color="primary"type="button" onClick={ this.startGame.bind(this) }> Start Game </Button>
</div>
<div className="hackerGame">
<GameScore score={this.state.gameScore} display={this.state.display} />
{ this.createFirewalls() }
<QuestionModal show={this.state.showQuizModal} onHide={addModalClose} context={this.state} score={this.state.gameScore} />
</div>
</div>
</section>
);
}
}
export default Hacker;
谢谢!
解决方法
this
并没有绑定到gameOver
回调,因此最终成为了承诺链中的undefined
。
在构造函数中将this
绑定到gameOver
constructor(props) {
super(props);
this.state ={
...
};
this.handleChange = this.handleChange.bind(this);
this.gameOver = this.gameOver.bind(this);
}
或将gameOver
转换为箭头函数,该函数将自动绑定调用者的this
gameOver = () => {
this.props.history.push({
pathname: `/gameover`,gameScore: this.state.gameScore,});
};
checkAnswer
是同步的,因此在排队状态更新之后 似乎正在排队。 this.props.onHide
在父组件中将addModalClose
设置为false,并关闭/卸载模态。尝试调整gameOver
的签名,以获取路由状态有效载荷,以在checkAnswer
排队到调用堆栈之前封装来自onHide
的组件状态的副本。
gameOver = (gameScore) => {
this.props.history.push({
pathname: `/gameover`,gameScore,});
};
传递状态值
} else {
console.log('incorrect');
swal("So close!",this.state.explanation,"error",{
closeOnClickOutside: false,buttons: {
confirm: "View your final score!"
},}).then (function() {
this.gameOver(this.state.gameScore); // <-- pass value
});
}
this.props.onHide();
注意:看来swal
控制着一些确认,并且this.props.onHide
是在.then
调用的swal
块之后触发的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。