切换导航标签时Redux重复添加Firestore查询列表数据问题求助
问题根因
- Redux 全局状态不会随组件卸载自动重置,你当前的
addItemreducer 逻辑为追加数据而非替换全量数据,每次组件重新挂载触发快照监听时,新拉取的全量数据会被追加到原有列表后。 - 本地状态属于组件内部状态,组件卸载时会自动销毁重置,因此不存在重复叠加问题。
解决方法
方案1:直接替换全量列表(推荐)
Firestore onSnapshot 默认首次触发会返回集合全量数据,直接替换列表即可,无需追加:
修改itemsSlice.js中addItem逻辑:
addItem: (state, action) => { // 直接覆盖原有列表,而非追加 state.items = action.payload; },
方案2:追加时做去重
如果业务确实需要增量追加逻辑,可通过Firestore文档唯一ID做去重判断,先调整数据拉取逻辑保留文档ID:
useEffect( () => { const unsubscribe = onSnapshot(collection(db, "users"), (snapshot) => { const firebaseData = snapshot.docs.map((doc) => ({ id: doc.id, // 保留文档唯一ID ...doc.data() })); dispatch(addItem(firebaseData)); setLocalState(firebaseData); }); // 组件卸载时清理监听器,避免内存泄漏 return () => unsubscribe(); }, [dispatch] );
再修改addItem逻辑做去重追加:
addItem: (state, action) => { // 过滤掉已存在的条目再追加 const uniqueNewItems = action.payload.filter( newItem => !state.items.some(existItem => existItem.id === newItem.id) ); state.items.push(...uniqueNewItems); },
方案3:切换页面时清空列表
如果业务要求离开当前页时清除列表数据,可在useEffect的清理函数中触发清空操作:
useEffect( () => { const unsubscribe = onSnapshot(collection(db, "users"), (snapshot) => { const firebaseData = snapshot.docs.map((doc) => doc.data()); dispatch(addItem(firebaseData)); setLocalState(firebaseData); }); // 卸载时同时清理监听器+清空Redux列表 return () => { unsubscribe(); dispatch(emptyItems()); } }, [dispatch] );
内容的提问来源于stack exchange,提问作者ErDevFy
相关产品推荐
相关产品推荐

