React useState数组状态插入对象数组异常及表单联动需求咨询
问题解决方案
核心问题根源
- React 的状态更新为异步批量执行,调用
setExam后不会立刻修改当前作用域内的exam变量,你在setExam之后立刻读取exam、存储localStorage、计算数组长度,用的都是更新前的旧值,直接导致提交顺序错误。 - 多处直接修改原state对象(比如
exam.subjectName = e.target.value、exam.questions[0].options[u] = e.target.value),不符合React不可变更新的要求,会引发状态更新异常、视图不刷新的问题。 - 单选框选中逻辑没有和答案状态绑定,无法自动同步选中值到答案输入框。
具体修改方案
1. 修复所有状态更新逻辑,禁止直接修改原state
所有状态修改都要走不可变更新,比如科目选择的修改逻辑调整为:
onChange={(e) => setExam((prevState) => ({ ...prevState, subjectName: e.target.value })) }
选项输入的修改逻辑调整为:
onChange={(e) => setExam((prevState) => { const newQuestions = [...prevState.questions] newQuestions[0].options[u] = e.target.value return { ...prevState, questions: newQuestions } }) }
2. 修复nextQuestion的异步更新问题
在状态更新回调内处理存储、下标计算逻辑,保证使用的是最新状态值:
const nextQuestion = () => { const que = exam?.questions?.[0]?.question; const examQuestionValues = exam.questions.map(ques => ques.question); // 原变量名写反,includes返回true说明题目重复 const isDuplicateQuestion = examQuestionValues.includes(que); if (isDuplicateQuestion) { alert("题目不能重复"); return; } const options = exam.questions[0].options; const optionsWithNoDuplicates = [...new Set(options)]; if (optionsWithNoDuplicates.length !== 4) { alert("选项不能重复"); return; } const newQuestion = { question: que, answer: value, options: optionsWithNoDuplicates, }; setExam((prevState) => { const newExam = { ...prevState, // 新增已完成题目,同时追加下一题的空模板 questions: [...prevState.questions, newQuestion, { question: "", answer: "", options: ["", "", "", ""], }] }; // 用最新状态存储到localStorage localStorage.setItem("exam", JSON.stringify(newExam)); setIndex(newExam.questions.length); return newExam; }); // 清空当前选中的答案,方便下一题使用 setValue(""); };
3. 实现单选框选中自动赋值答案
调整单选框的onChange逻辑,直接同步选中值到答案状态即可:
<FormControlLabel control={<Radio />} onChange={(e) => setValue(e.target.value)} value={item.options[u]} disabled={!item.options[u].length} />
答案输入框已经绑定了value状态,修改后选中单选框会自动同步值到输入框。
内容的提问来源于stack exchange,提问作者Shubham Sanchela
相关产品推荐
相关产品推荐

