我对编程很陌生,目前正在使用React.js和API。
我正在尝试使此测验API https://opentdb.com/api.php?amount=10&category=20&difficulty=medium在我的应用中进行响应。
到目前为止,我已经获取了所需的所有信息,但是单击时希望应用程序显示我是否单击了json中的correct_answer还是不正确_answer,并显示了包含信息的文本框。单击10次后,它应该停止计数并显示结果,这就是我遇到的问题,需要一些帮助。
这是我到目前为止得到的:
import React, { Component } from "react";
import "./App.css";
const API =
"https://opentdb.com/api.php?amount=10&category=20&difficulty=medium";
class App extends Component {
constructor(props) {
super(props);
this.state = {
results: [],
score: 0,
correct_answer: "",
incorrect_answers: ""
};
}
handleClick = event => {
this.setState({
score: this.state.score + 1,
correct_answer: event.target.value,
incorrect_answers: event.target.value
});
};
componentDidMount() {
this.populateAppWithData();
}
populateAppWithData() {
const showData = fetch(API)
.then(response => response.json())
.then(data => this.setState({ results: data.results }));
console.log(showData);
}
render() {
var {} = this.state ? "You are correct" : "You are incorrect";
console.log();
const results = this.state.results.slice().map((result, index) => (
<ul onClick={this.handleClick.bind(this)} key={"result" + index}>
<li>
<h2> {result.question}</h2>
{""}
<h5>{result.correct_answer}</h5>
</li>
{result.incorrect_answers.map(incAnswer => (
<li>
<h5>{incAnswer}</h5>
</li>
))}
</ul>
));
return (
<div className="App">
<h1>Quiz App</h1>
<div>{results[Math.floor(Math.random() * results.length)]}</div>
<div>Score: {this.state.score}</div>
</div>
);
}
}
export default App;
答案 0 :(得分:0)
让我们从头开始。因为每个问题都可以被回答或被回答,对与错,所以它必须具有自己的状态。因此,它必须是其自己的组件。因此,让我们构建一个Question
组件,该组件需要一个正确的答案和一些不正确的答案以及一个问题,并在问题得到回答时回叫:
class Question extends Component {
state = { answered: undefined, isRight: undefined };
answerClicked(answer) {
const { hasAnswered, correct_answer } = this.props;
return event => {
if(this.state.answered) return; // prevent answering twice
const isRight = correct_answer === answer;
hasAnswered(isRight); // propagate to parent
this.setState({ answered: answer, isRight });
};
}
render() {
const { question, correct_answer, incorrect_answers } = this.props;
const { answered, isRight } = this.state;
return (
<div>
{question}
{[...incorrect_answers, correct_answers]/*shuffle?*/.map(answer => <div onClick={this.answerClicked(answer)} > {answer} </div>)}
{answered && `You answered ${answered}`}
{answered && isRight && "Thats right! :)"}
{answered && !isRight && "That's wrong :/"}
</div>
);
}
}
到目前为止,一切都很好。现在您可以添加:
<Question question="Whats the answer to life the universe and everything?" correct_answer="42" incorrect_answers={["15", "12"]} hasAnswered={right => alert(right ? "Right" : "Wrong")} />
在某个地方,看到一个问题:)
下一步:我们要对多个问题进行分组并添加一个计数器。为此,我们使用了另一个组件,该组件可以建立Question
并在其状态下保持一个计数器,已经回答了多少个问题以及正确回答了多少个问题。
class Questions extends Component {
state = { right: 0, counter: 0 };
questionAnswered(isRight) {
this.setState(({ counter, right }) => ({ counter: counter + 1, right: right + isRight }));
}
render() {
const { questions } = this.props;
const { counter, right } = this.state;
const unanswered = questions.length - counter;
if(unanswered <= 0) {
return `All answered!`;
}
return (
<div>
You have {unanswered} questions left, {right} are rigjt already!
{ questions.map(it => <Question key={it.question} {...it} hasAnswered={it => this.questionAnswered(it)} />) }
</div>
);
}
}
再次,我们可以轻松测试应用程序的这一部分:
<Questions questions={[{ question: "What is the answer to life, the universe and everything?", correct_answer: "42", incorrect_answers: ["52", "12"] }, /*...*/]} />
现在剩下的唯一事情就是让App加载问题并在问题可用时使用<Questions />
组件。
通过这种拆分,我们确实将关注点分开了:
<Question>
类管理与提出问题和给出“每个问题的反馈”有关的任何事情
<Questions>
组件管理多个问题,并在回答所有问题时提供总体反馈。
<App>
组件会加载问题。