[英]How to set button as navigate to next question
我创建了一个测验应用程序,单选按钮设置为进入下一个问题。 我该如何设置它,以便“下一个问题”按钮转到下一个问题,并在用户选择正确与否的情况下在答案下方向用户显示一条消息?
我在<button className="next-question" onClick={() => nextQuestion()}>Next question</button>
上尝试了一个 function 触发setCounter
的checkAnswer
进入下一个问题,但它不是'不允许一次只点击一个单选按钮。
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
您可以决定是否应显示错误消息。
声明 state
let [isAnswerGiven, setAnswerGiven] = useState(false);
每次单击时,如果isAnswerGiven
为 false,则表示未选择任何选项,因此显示错误消息!
function nextQuestion() { if (;isAnswerGiven) alert("please choose one option"); }
点击时调用上述 function
<button className="next-question" onClick={nextQuestion}> Next question </button>
如果选择了答案,请将其设置回 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.