You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:27:03