React使用useState追加状态值时覆盖原对象数组问题求助
问题根源
当前代码每次更新都会覆盖people数组,核心原因有2个:
handleChange2中给people赋值时,直接传入了仅包含当前输入值的全新单元素数组,没有展开保留原有数组的历史数据- 逻辑位置错误:输入过程中的
onChange事件不应该直接修改存储人员列表的状态,追加新值的操作应该放在表单提交时触发,输入过程的临时值需要单独存储。另外输入框的value错误绑定到了顶层状态的email字段,和people数组结构不匹配。
修复步骤
- 单独声明一个状态存储输入框的临时输入值,避免输入过程中频繁改动人员列表状态
- 把追加新人员的逻辑迁移到
handleSubmit提交事件中,更新people数组时先展开原有数组内容,再拼接新的人员对象 - 推荐使用函数式更新写法修改状态,避免闭包缓存导致拿到旧状态值,引发更新异常
- 提交成功后清空输入框的临时值,方便下一次输入
修复后完整代码
import {useState} from 'react'; const initialState = { people: [ {email: 'Jan'}, {email: 'Izabela'}, {email: 'Michael'} ] } const StateModification = () => { const [names, setNames] = useState(initialState) // 单独存储输入框临时值 const [inputEmail, setInputEmail] = useState('') const handleSubmit = (e) => { e.preventDefault(); // 提交时追加新值到people数组 setNames(prevState => ({ ...prevState, people: [...prevState.people, {email: inputEmail}] })) // 提交后清空输入框 setInputEmail('') } const handleInputChange = (e) => { // 输入时只更新临时值 setInputEmail(e.target.value) } return ( <div> <form onSubmit={handleSubmit}> <label>E-mail</label> <input id='email' type='text' name='email' value={inputEmail} onChange={handleInputChange} /> <button type='submit'>Add</button> </form> {/* 可选:渲染当前people列表验证效果 */} <ul> {names.people.map((person, idx) => <li key={idx}>{person.email}</li>)} </ul> </div> ) } export default StateModification;
如果需要在输入过程中实时更新而不是点提交才追加,只需要注意每次更新
people时都要先展开旧数组:people: [...names.people, {[e.target.name]: e.target.value}],但这种交互会导致每输入一个字符就新增一条数据,不符合常规表单使用逻辑,不推荐使用。
内容的提问来源于stack exchange,提问作者Kohler
相关产品推荐
相关产品推荐

