如何在JavaScript数组中移除并重新添加对象?React闪卡开发问题
问题根源分析
- 你用普通全局数组
learnedCards存数据,没有纳入React状态管理,不仅组件重渲染后数据会丢失,React也无法感知这个数组的变化驱动UI更新 setIsLearned是异步更新操作,调用后当前作用域拿到的isLearned还是更新前的旧值,判断逻辑完全错位- 你写的去重逻辑只保留出现次数为1的元素,当第三次点击添加同一张卡片时,该卡片序列化后的字符串出现次数变为3,会被直接过滤掉,自然没法重新添加
- 生成的去重后数组
updatedLearnedCards没有赋值给原数组,全局数组里的重复数据会越攒越多,后续判断逻辑会完全失效 - 单张卡片维度的
isLearned状态和全局已学卡片数组没有做关联,状态不同步
修复方案
首先你需要把全局已学卡片数组改成React状态管理,推荐每个卡片提前分配唯一ID(没有的话可以用character + pinyin的组合作为唯一标识),然后通过判断标识是否存在来决定添加还是移除:
// 全局用useState存已学卡片数组,可放在父组件或者Context里实现跨页面共享 const [learnedCards, setLearnedCards] = useState([]); // 单个闪卡组件内的点击逻辑 const addRemoveCard = () => { // 生成当前卡片的唯一标识,避免用JSON序列化判断相等的问题 const cardId = `${character}-${pinyin}`; const currentCard = { id: cardId, character, pinyin, english, type }; // 用函数式更新状态,避免闭包导致的旧值问题 setLearnedCards(prev => { const isExisted = prev.some(card => card.id === cardId); if (isExisted) { // 已存在则移除对应卡片 return prev.filter(card => card.id !== cardId); } else { // 不存在则新增卡片 return [...prev, currentCard]; } }); // 同步更新当前卡片的选中状态 setIsLearned(prev => !prev); };
补充优化点
- 如果需要持久化已学卡片数据,可以在更新
learnedCards的同时同步写入localStorage,刷新页面后数据也不会丢失 - 如果卡片数量很大,可以改用
Set结构存已学卡片的ID,判断存在的时间复杂度会从O(n)降到O(1),性能更好
内容的提问来源于stack exchange,提问作者sgt_pepper85
相关产品推荐
相关产品推荐

