从api上获取有关点击的某些信息,并在单击10次后停止

时间:2019-04-28 15:41:32

标签: javascript json reactjs api

我对编程很陌生,目前正在使用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;

1 个答案:

答案 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>组件会加载问题。