开发者

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);
  };
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜