我正在Reactjs、中创建一个测验应用程序
问题是,当我尝试选择一个选项时,它会被选中,但如果我尝试选择另一个选项,它也会被选中。我想要如果选择了A,如果用户点击了B,A将被取消选择,B将被选中。
我试着在子组件和父组件中都这样做。在Child中,我可以选择一个div,但如果我单击另一个选项,它们也会被选中。在"父项"中,当我尝试选择任何选项时,它就是选择所有选项。
Option.js(子组件(
import React, { useState } from 'react'
function Option({ index, item, changeIndexValue }) {
const [currentOptionSelected, setCurrentOptionSelected] = useState(false)
const handleClick = (index) => {
changeIndexValue(index)
setCurrentOptionSelected(prevState => !prevState)
}
return (<>
<div className='option'
style={{ border: currentOptionSelected ? "2px solid red" : "1px solid black" }}
onClick={() => handleClick(index)}
key={index}
><p>{item}</p>
</div>
</>
)
}
export default Option
QuizMain.js(父组件(
import React, { useState } from 'react'
import ProgressBar from '../ProgressBar/ProgressBar';
import './QuizMain.css'
import { useNavigate, useLocation } from 'react-router-dom';
import { useOutletContext } from "react-router-dom";
import ScoreCard from '../ScoreCard/ScoreCard';
import Option from '../Option/Option';
function QuizMain() {
const [currentQuestion, setCurrentQuestion] = useState(0)
const [changeCurrentQuestion, currentQuestionNumber, questionAre] = useOutletContext();
const [finalReport, setFinalReport] = useState([]);
const [finalReportVisible, setFinalReportVisible] = useState(false)
const [correctAnswer, setCorrectAnswer] = useState("")
const changeCorrectAnswer = (value) => {
setCorrectAnswer(value)
}
const [indexValue, setIndexValue] = useState("")
const changeIndexValue = (value) => {
setIndexValue(value)
}
const location = useLocation();
const { chooseQuizType } = location.state;
console.log(chooseQuizType, 'location')
const handleSubmit = () => {
const answersCurrentQuestion = questionAre[currentQuestionNumber].options.map((item) => item)
if (chooseQuizType == "withAnsers") {
console.log(answersCurrentQuestion[indexValue], 'selected option')
if (answersCurrentQuestion[indexValue] == questionAre[currentQuestionNumber].correctAnswer) {
alert('Correct answer')
} else {
alert('Wrong answer')
changeCorrectAnswer(questionAre[currentQuestionNumber].correctAnswer)
}
}
setFinalReport(prevState => [...prevState, {
question: questionAre[currentQuestionNumber].question,
correctAnswer: questionAre[currentQuestionNumber].correctAnswer,
yourAnswer: answersCurrentQuestion[indexValue]
}])
}
return (<>
{finalReportVisible ? <ScoreCard finalReport={finalReport} /> :
<div className='quizMain'>
<div className='quizMain__main'>
<div className='questions'>
<h3>{questionAre && questionAre[currentQuestionNumber]?.question}</h3>
</div>
<div className='options'>
{questionAre && questionAre[currentQuestionNumber]?.options.map((item, index) => {
return <Option
key={index}
item={item}
index={index}
changeCorrectAnswer={changeCorrectAnswer}
correctAnswer={correctAnswer}
indexValue={indexValue}
changeIndexValue={changeIndexValue}
/>
})}
<p>{correctAnswer}</p>
</div>
<div className='submit__button'>
<button onClick={handleSubmit}>Submit</button>
</div>
</div>
</div >
}
</>
)
}
export default QuizMain
在React中,应避免在子组件中放入过多逻辑。子组件应该用来显示信息,让父容器处理逻辑。
在QuizMain.js(Parent(中,定义一个状态来控制当前选择的选项
const [selected, setSelected] = useState(-1); // -1 means non is selected
还定义了一个函数,该函数将传递给选项组件(子组件(以更新选择
const selectOption = (option) => {
setSelected(option);
}
在Option.js(Child(中,包括以下内容来支持
function Option({ index, item, onSelect, selected })
对于Option.js的onClick回调,只需将onSelect(index(放入
onPress={ () => onSelect(index) }
回到QuizMain.js,每个Option组件都应该像一样
<Option
...
key={ index }
selected={ selected === index }
/>