繁体   English   中英

如何将按钮设置为导航到下一个问题

[英]How to set button as navigate to next question

我创建了一个测验应用程序,单选按钮设置为进入下一个问题。 我该如何设置它,以便“下一个问题”按钮转到下一个问题,并在用户选择正确与否的情况下在答案下方向用户显示一条消息?

我在<button className="next-question" onClick={() => nextQuestion()}>Next question</button>上尝试了一个 function 触发setCountercheckAnswer进入下一个问题,但它不是'不允许一次只点击一个单选按钮。

function App() {
  let [points, setPoints] = useState(null);
  let [counter, setCounter] = useState(null);
  let [question, setQuestions] = useState();
  let [is_started, setStart] = useState(false);
  let [is_end, setEnd] = useState(false);

  function Answer(props) {
    return (
      <li aria-labelledby='answers-list'>
        <label><input type="radio" className="answer" data-correct={props.correct} onChange={props.checkAnswer}/>{props.answer}</label>
      </li>
    );
  }
  
  function Quiz(props) {
    return (
      <div className="quiz">
        <div className="question" role="h2">{props.question}</div>
        <ul className="answers">{props.children}</ul>
      </div>
    );
  }

  function checkAnswer(e) {
    if (e.target.dataset.correct === "true") {
      setPoints(points + 1);
    }

    let nextQuestion = counter + 1;
    if (counter < question.length - 1) {
      setCounter(nextQuestion);
    } else {
      setEnd(!is_end);
      setStart(!is_started);
      setCounter(0);
    }
  }

  return (
    <div className="Quiz">
      {!is_started ? (
      <div className="start-intro-wrapper">
        <h1 className="name">Quiz App</h1>
        <Starter start={start} />
      </div>
      ):(
        <div className="quick-wrapper">
          <Quiz question={question[counter].question}>
            {question[counter].answers.map((answer, index, arr) => {
              return (
                <Answer
                  key={index}
                  answer={answer.value}
                  checkAnswer={checkAnswer}
                  correct={answer.correct ? "true" : "false"}
                />
              );
            })}
          </Quiz>
          <button className="next-question">Next question</button>
        </div>)}
      {is_end && <div className="results-container"><ScoreMessage score={points} /></div>}
    </div>
  );
}

export default App;

Codesandbox 中的当前state

实例化另一个 state 以跟踪无线电选择,通过true/false您可以决定是否应显示错误消息。

  1. 声明 state

     let [isAnswerGiven, setAnswerGiven] = useState(false);
  2. 每次单击时,如果isAnswerGiven为 false,则表示未选择任何选项,因此显示错误消息!

     function nextQuestion() { if (;isAnswerGiven) alert("please choose one option"); }
  3. 点击时调用上述 function

     <button className="next-question" onClick={nextQuestion}> Next question </button>
  4. 如果选择了答案,请将其设置回 false。

     useEffect(() => { setAnswerGiven(false); }, [counter]);

这是一个完整的工作示例。

这是您指定的一种实现

import React, { useState, useEffect } from "react";
import "./styles.css";

function App() {
  let [points, setPoints] = useState(null);
  let [counter, setCounter] = useState(null);
  let [question, setQuestions] = useState();
  let [is_started, setStart] = useState(false);
  let [is_end, setEnd] = useState(false);

  const getData = () => {
    fetch("./questions.json")
      .then(function (response) {
        return response.json();
      })
      .then(function (data) {
        setQuestions(data);
      });
  };
  useEffect(() => {
    getData();
  }, []);

  function Answer(props) {
    return (
      <li aria-labelledby="answers-list">
        <label>
          <input
            type="radio"
            name="answer_group"
            className="answer"
            value={props.answer}
          />
          {props.answer}
        </label>
      </li>
    );
  }

  function Starter(props) {
    return (
      <button className="starter" onClick={props.start}>
        {is_end ? "Restart" : "Start"}
      </button>
    );
  }

  function Quiz(props) {
    return (
      <div className="quiz">
        <div className="quesiton" role="h2">
          {props.question}
        </div>
        <ul className="answers">{props.children}</ul>
      </div>
    );
  }

  function start() {
    setCounter(0);
    setPoints(0);
    setStart(!is_started);
    setEnd(false);
  }

  function displayCorrect(correct) {
    let correct_msg = correct ? "correct" : "incorrect";
    console.log("Answer was " + correct_msg);
  }

  function nextQuestion() {
    if (document.querySelector('input[name="answer_group"]:checked') == null) {
      alert("Must select an answer before proceeding to the next question");
      return;
    }
    let val = document.querySelector('input[name="answer_group"]:checked')
      .value;
    let answerObj = question[counter].answers.filter(
      (ans) => ans.value === val
    )[0];
    let updated_points = answerObj.correct ? points + 1 : points;
    console.log(updated_points);
    setPoints(updated_points);
    let nextQuestion = counter + 1;
    if (counter < question.length - 1) {
      setCounter(nextQuestion);
    } else {
      setEnd(!is_end);
      setStart(!is_started);
      setCounter(0);
    }
    displayCorrect(answerObj.correct);
  }

  return (
    <div className="Quiz">
      {!is_started ? (
        <div className="start-intro-wrapper">
          <h1 className="name">Quiz App</h1>
          <Starter start={start} />
        </div>
      ) : (
        <div className="quick-wrapper">
          <Quiz question={question[counter].question}>
            {question[counter].answers.map((answer, index, arr) => {
              return (
                <Answer
                  key={index}
                  index={index}
                  answer={answer.value}
                  correct={answer.correct}
                />
              );
            })}
          </Quiz>
          <button className="next-question" onClick={(e) => nextQuestion()}>
            Next question
          </button>
        </div>
      )}
    </div>
  );
}

export default App;

沙盒中的所有代码

编辑:一旦选择了单选按钮作为 OP 评论,就会包含反馈。

function Answer(props) {
    return (
      <li aria-labelledby="answers-list">
        <label>
          <input
            type="radio"
            name="answer_group"
            className="answer"
            value={props.answer}
            onChange={checkAnswer}
          />
          {props.answer}
        </label>
      </li>
    );
  }

  function checkAnswer(e) {
    let val = e.target.value;
    let ans = question[counter].answers.filter((ans) => ans.value === val)[0];
    displayCorrect(ans.correct);
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM