React中通过onChange处理Quiz App表单的answers数组输入问题
解决Quiz App中AddQuestion组件的答案输入同步问题
问题分析
当前代码存在两个核心问题,导致只有最后一个答案输入框的值能同步到state:
- 每次触发
onChange时,未赋值的firstAnswer/secondAnswer等变量会是undefined,更新answers时会覆盖其他答案的text为undefined - 错误地将
answers从数组转换成了对象,破坏了原有状态结构,同时丢失了每个答案的id和correctAnswer字段
解决方案
通过以下修改实现答案输入的正确同步:
- 统一输入框命名规则:将答案输入框的
name设置为answer-{index},直接关联answers数组的下标 - 重构
onChange函数:区分普通字段(title/description)和答案字段,针对答案字段,复制原数组并更新对应项的text,保留其他字段的完整数据 - 保留数组结构:始终维护
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
相关产品推荐
相关产品推荐

