保存钩子数组报错:Uncaught TypeError: choices is not iterable问题排查
问题原因及解决方案
1. 核心错误:push方法返回值导致状态异常
你在handleChoice函数里犯了一个关键错误:
push()方法的返回值是数组的新长度(数字),而非修改后的数组本身。- 执行
updatedAnswers = [...choices].push(e.target.value)后,updatedAnswers被赋值成了数字,调用setChoices(updatedAnswers)会把choices状态从数组替换成数字。 - 下次触发函数时,
[...choices]试图展开一个非数组类型的数字,就会抛出“choices is not iterable”的错误。
修复后的handleChoice函数
const handleChoice = (e) => { // 直接生成包含原有元素和新值的新数组 const updatedAnswers = [...choices, e.target.value]; console.log(updatedAnswers); setChoices(updatedAnswers); // 同步更新value状态,确保单选框显示选中状态 setValue(e.target.value); };
2. 额外问题:所有单选框共用同一分组
你给所有RadioGroup设置了相同的name="quiz",这会让所有题目选项归为同一单选组,用户同一时间只能选中一个选项,无法完成多题作答。
修复方法:给每个分组设置唯一标识
利用map的index生成唯一name,同时调整状态结构来存储每个题的选中值:
{exercises && exercises.map((exercise, index) => ( <div key={index}> <FormLabel id={`demo-error-radios-${index}`}>Question {index+1}: {exercise.question}</FormLabel> <RadioGroup aria-labelledby={`demo-error-radios-${index}`} name={`quiz-${index}`} // 用index生成唯一分组名 value={values[index] || ''} // 对应每个题的选中值 onChange={(e) => handleChoice(e, index)}> <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> ))}
同时修改状态定义和handleChoice函数,适配多题的选中状态存储:
// 用对象存储每个题的选中值,数组存储最终答案 const [values, setValues] = useState({}); const [choices, setChoices] = useState([]); const handleChoice = (e, index) => { const selectedValue = e.target.value; // 更新对应题目的选中状态 setValues(prev => ({...prev, [index]: selectedValue})); // 更新choices数组,确保每个位置对应对应题目的答案 const updatedChoices = [...choices]; updatedChoices[index] = selectedValue; setChoices(updatedChoices); };
内容的提问来源于stack exchange,提问作者Pog master
相关产品推荐
相关产品推荐

