Error when saving hook arrays, Uncaught TypeError: choices is not iterable
I am trying to create a simple MCQ exam form with choices and answers, whenever the user selects a choice, it is supposed to be added in to the array of choices.
Initially I have an array named exercises, which contains exercise objects, each object contains a question and 4 different choices and an answer => for example:
exercises = {
"question": "What is 2+2?",
"firstChoice": "1",
"secondChoice": "2",
"thirdChoice": "3",
"fourthChoice": "4",
"answer":"4"
}
Initially choices array, and value
const [value,setValue] = useState('');
const [choices,setChoices] = useState([]);
And this is the RadioGroup:
{exercises && exercises.map((exercise,index)=>(
<div>
<FormLabel id="demo-error-radios">Question {index+1}: {exercise.question}</FormLabel>
<RadioGroup
aria-labelledby="demo-error-radios"
name="quiz"
value={value}
onChange开发者_开发百科={(e) => {handleChoice(e)}}>
<FormControlLabel value={exercise.firstChoice} control={<Radio />} label= {exercise.firstChoice} />
<FormControlLabel value={exercise.secondChoice} control={<Radio />} label={exercise.secondChoice} />
<FormControlLabel value={exercise.thirdChoice} control={<Radio />} label={exercise.thirdChoice} />
<FormControlLabel value={exercise.fourthChoice} control={<Radio />} label={exercise.fourthChoice}/>
</RadioGroup>
</div>
))}
This is the handleChoice function, whenever an input of type radio is clicked, it pushes that value in to the array of choices.
const handleChoice = (e) =>{
var updatedAnswers = [...choices];
updatedAnswers = [...choices].push(e.target.value);
console.log(updatedAnswers);
setChoices(updatedAnswers);
}
When I try to run it, I get always the error "Uncaught TypeError: choices is not iterable", It is supposed to be updating the array of choices by adding the new selected choice to the old ones, Why does not it work?
[...choices].push returns a number, which is the length of the new array. After that you setChoices(updatedAnsers), which turns choices into a number, so the next time choices is spread, it throws error because number is not iterable. Instead try this:
const handleChoice = (e) =>{
var updatedAnswers = [...choices, e.target.value];
console.log(updatedAnswers);
setChoices(updatedAnswers);
}
In your handleChoice
method, you are setting choices to the return value of the push
method.
updatedAnswer = [...choices].push(e.target.value)
This sets updatedAnswer
to the array length (push returns the new array length). What you want is to just append to choices so that can be done as follows:
setChoices([...choices, e.target.value])
In fact the entire function could be simplified:
const handleChoice = ({ target: { value } }) => setChoices([...choices, value])
The return value of push
is the array's new length. So when you write:
updated = [...choices].push(e.value.target);
updated
is initially assigned 1
, and that is what is save to state, and 1
(on the next choice) is not iterable, hence the error.
Change the code to:
const updated = [...choices, e.target.value];
setChoices(updated);
You could try something like this in your handleChoice function:
const handleChoice = (e) => {
var updatedAnswers = choices;
updatedAnswers.push(e.target.value);
console.log(updatedAnswers);
setChoices(updatedAnswers);
};
精彩评论