React投票应用:如何更新State对象文本而非重复创建对象?
解决React投票应用中答案输入框的更新问题
核心问题分析
你当前的appendAnswers函数每次触发onChange时都会向answers数组添加新对象,根本没有区分是哪个输入框的输入操作,所以会出现每输入一个字符就新增一条数据的情况。要实现同一输入框输入时更新对应对象,固定输入框对应固定答案对象的需求,需要给每个输入框绑定唯一标识,针对性更新数组中的对应元素。
具体实现方案
1. 初始化对应数量的答案对象
因为你有3个答案输入框,初始化answers时直接创建3个包含默认字段的对象,每个对象对应一个输入框:
const [question, setQuestion] = useState(''); const [answers, setAnswers] = useState([ { text: '', votesCount: 0 }, { text: '', votesCount: 0 }, { text: '', votesCount: 0 } ]);
2. 给每个输入框绑定索引标识
修改表单中的StyledInput,传递对应的索引值,让处理函数明确要更新哪个对象:
<span>Question <StyledInput onChange={(e) => setQuestion(e.target.value)}></StyledInput> ? </span> <span className='answers'>Answer 1 <StyledInput onChange={(e) => updateAnswer(e, 0)}></StyledInput> .</span> <span className='answers'>Answer 2 <StyledInput onChange={(e) => updateAnswer(e, 1)}></StyledInput> . </span> <span className='answers'>Answer 3 <StyledInput onChange={(e) => updateAnswer(e, 2)}></StyledInput> .</span>
3. 编写针对性的更新函数
使用React的函数式更新(避免闭包导致的state旧值问题),复制原数组并更新对应索引的对象:
function updateAnswer(e, index) { const inputValue = e.target.value; setAnswers(prevAnswers => { // 复制原数组,不可直接修改state const updated = [...prevAnswers]; // 替换对应索引的对象,保留原有votesCount等字段 updated[index] = { ...updated[index], text: inputValue }; return updated; }); }
更简洁的写法(可选)
可以用数组的map方法简化更新逻辑,代码更紧凑:
function updateAnswer(e, index) { const inputValue = e.target.value; setAnswers(prevAnswers => prevAnswers.map((answer, idx) => idx === index ? { ...answer, text: inputValue } : answer ) ); }
效果验证
现在每个输入框输入内容时,只会更新answers数组中对应索引的对象的text字段,不会再新增对象。比如在Answer 1输入框输入"Hello",answers[0].text会逐步更新为"H"→"He"→"Hel"→"Hell"→"Hello",而数组始终保持3个元素。
内容的提问来源于stack exchange,提问作者bogyz123
相关产品推荐
相关产品推荐

