React中使用setState向数组添加对象失败相关问题咨询
表单提交后users数组为空的原因
- 原生
<form>标签默认的提交行为会触发页面全局刷新,页面刷新后所有组件状态会被重置为初始值,你调用setState更新的数组内容会随着页面刷新被清空,所以打印出来始终是空数组。 - 调用
e.preventDefault()的作用是阻止表单的默认提交行为,页面不会刷新,组件状态的更新就能正常保留。 - 另一个项目不需要加该代码也能正常运行的常见可能性:
- 该项目没有使用原生form的
onSubmit事件,而是给普通按钮绑定了onClick事件触发提交逻辑,本身不会触发默认提交刷新 - 项目引入了Formik、React Hook Form等表单处理库,这类库内部默认已经阻止了表单的默认提交行为
- 之前的提交逻辑最后返回了
false,原生表单事件中返回false也会阻止默认行为
- 该项目没有使用原生form的
列表key属性警告的原因
React在处理列表渲染时,需要通过唯一的key属性标识每一个列表子元素,用于虚拟DOM的diff对比,精准判断哪些元素发生了增删改,提升渲染性能、避免渲染异常。
你当前代码中遍历users数组返回UserCard组件时没有传入key属性,就会触发该警告。
修复方案
- 提交用户信息时给每个用户对象添加唯一标识:
onSubmitHandler = (e) => { e.preventDefault() const Person = { id: Date.now(), // 新增唯一id,时间戳可满足简单场景的唯一性要求 name: this.state.currentUser, age: this.state.currentAge, }; this.setState({ users: [...this.state.users, Person], }); };
- 渲染时给
UserCard绑定key属性:
{this.state.users.map((user) => { return <UserCard key={user.id} name={user.name} age={user.age} />; })}
如果你的业务场景中用户名不会重复,也可以临时用name作为key值;如果是完全静态不会发生增删排序的列表,也可以用map的第二个参数索引作为key,但该方式不推荐用于动态列表,可能会引发渲染异常。
内容的提问来源于stack exchange,提问作者Chener Zhang
相关产品推荐
相关产品推荐

