React中如何向数组类型的state中添加对象元素?
解决方案
原有代码的问题
- 用
map遍历查找元素不符合使用场景,map是用来生成新数组的,查找元素更适合用find - 直接调用
setSelectedTag(tag)会把原本是数组类型的selectedTag直接覆盖为单个对象,完全不符合追加元素的需求 - 没有遵循React状态不可变的更新原则,不能直接修改原状态数组,必须传入新的数组引用触发更新
正确实现代码
基础版(支持追加元素)
const addTag = (id: number) => { // 查找匹配id的tag对象 const targetTag = tags.find(tag => tag.id === id); // 找到匹配项才执行更新 if (targetTag) { // 函数式更新拿到最新的历史选中列表,展开后追加新元素生成新数组 setSelectedTag(prevSelected => [...prevSelected, targetTag]); } }
优化版(避免重复添加相同tag)
如果需要防止同一个tag被多次加入选中列表,可以增加重复判断:
const addTag = (id: number) => { const targetTag = tags.find(tag => tag.id === id); if (targetTag) { setSelectedTag(prevSelected => { // 校验当前tag是否已经在选中列表中 const isAlreadySelected = prevSelected.some(tag => tag.id === id); // 已经存在就返回原状态,不存在就返回追加后的新数组 return isAlreadySelected ? prevSelected : [...prevSelected, targetTag]; }); } }
核心原理
- React的状态更新要求传入全新的引用值才会触发重渲染,直接对原数组执行
push等修改操作不会生效 - 使用函数式更新的写法可以保证每次拿到的
prevSelected都是最新的状态值,避免闭包导致的状态陈旧问题 Array.find比map更适合查找场景,匹配到目标后就会终止遍历,性能更好
内容的提问来源于stack exchange,提问作者user16516348
相关产品推荐
相关产品推荐

