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

React中通过onChange处理Quiz App表单的answers数组输入问题

解决Quiz App中AddQuestion组件的答案输入同步问题

问题分析

当前代码存在两个核心问题,导致只有最后一个答案输入框的值能同步到state:

  • 每次触发onChange时,未赋值的firstAnswer/secondAnswer等变量会是undefined,更新answers时会覆盖其他答案的text为undefined
  • 错误地将answers从数组转换成了对象,破坏了原有状态结构,同时丢失了每个答案的id和correctAnswer字段

解决方案

通过以下修改实现答案输入的正确同步:

  1. 统一输入框命名规则:将答案输入框的name设置为answer-{index},直接关联answers数组的下标
  2. 重构onChange函数:区分普通字段(title/description)和答案字段,针对答案字段,复制原数组并更新对应项的text,保留其他字段的完整数据
  3. 保留数组结构:始终维护answers的数组类型,不随意转换为对象

修改后的完整代码

function AddQuestion(props) {
  const [question, setQuestion] = useState({
    title: "",
    description: "",
    answers: [
      { id: 0, text: "", correctAnswer: false },
      { id: 1, text: "", correctAnswer: false },
      { id: 2, text: "", correctAnswer: false },
      { id: 3, text: "", correctAnswer: false }
    ],
    clicked: false
  });

  const onChange = (e) => {
    const { name, value } = e.target;
    
    // 处理普通字段(title/description)
    if (name === "title" || name === "description") {
      setQuestion(prev => ({
        ...prev,
        [name]: value
      }));
      return;
    }

    // 处理答案字段:解析出对应的数组索引
    if (name.startsWith("answer-")) {
      const index = parseInt(name.split("-")[1]);
      setQuestion(prev => ({
        ...prev,
        answers: prev.answers.map((answer, idx) => {
          if (idx === index) {
            // 只更新当前输入的答案text,保留id和correctAnswer
            return { ...answer, text: value };
          }
          return answer;
        })
      }));
    }
  };

  return (
    <div className={style.newQuestionForm}>
      <h1>Add a New Question</h1>
      <label>Title: <br /> <input type="text" name="title" onInput={onChange}/></label>
      <label>Description:<br/><input type="text" name="description" onInput={onChange}/></label>
      
      {/* 循环生成答案输入框,也可以手动写四个,命名对应answer-0到answer-3 */}
      {question.answers.map((_, index) => (
        <label key={index}>
          {`Answer ${index + 1}:`}<br />
          <input 
            type="text" 
            name={`answer-${index}`} 
            value={question.answers[index].text} // 增加value绑定,实现双向同步
            onInput={onChange}
          />
        </label>
      ))}
     
      <div className={style.btnDiv}>
        <button className={style.newQuestionBtn} onClick={() => props.onAdd(question)}> 
            Add New Question
        </button>
      </div>
    </div>
  );
}

关键修改说明

  • 输入框value绑定:给答案输入框增加value={question.answers[index].text},确保输入框显示的内容与state完全同步
  • 数组更新逻辑:使用map方法更新answers数组,只修改目标索引对应的项,其他项保持不变,避免丢失原有数据
  • 字段区分处理:通过name前缀判断是否为答案字段,逻辑更清晰,扩展性更好(比如后续增加更多答案选项时无需修改函数)

内容的提问来源于stack exchange,提问作者Idok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:05:31