React SPA路由切换后组件状态数据重复翻倍问题求助
解决React SPA中Home路由数据翻倍的问题
嘿,别着急!我看了你的代码,马上就发现了问题所在——你踩了个Redux状态更新的常见小坑,咱们一步步来修复:
核心问题:Reducer中错误的状态累加
你怀疑的没错,问题主要出在Reducer的FETCHED_PRODUCTS处理逻辑里:
case FETCHED_PRODUCTS: return { ...state, products: state.products.concat(action.payload), // 这里是罪魁祸首! loading: false, error: false, };
每次调用getProducts获取数据时,你用concat把新数据拼接到旧数据后面,而不是直接替换旧数据。这就导致:
- 第一次进入Home:获取到完整产品列表,state里的products是正常数量
- 切换到Upload再返回Home:又获取一次完整列表,拼接到旧数据后,数据直接翻倍
- 重复切换的话,数据会一直叠加增长
修复方案:替换而不是拼接数据
把Reducer里的这一行改成直接赋值:
case FETCHED_PRODUCTS: return { ...state, products: action.payload, // 直接用新获取的完整数据替换旧数据 loading: false, error: false, };
这样每次回到Home路由获取数据时,都会用最新的完整列表覆盖旧状态,彻底解决数据翻倍的问题。
次要优化:避免不必要的重渲染与错误的key值
除了核心问题,还有两个小细节可以优化,让你的组件更稳健:
1. 用数据的唯一ID作为列表项的key
你现在用uuid.v4()生成key,这会导致每次渲染React都认为是新的列表项,无法复用组件,影响性能。改成用数据自带的唯一标识d._id:
// 把原来的key={uuid.v4()}改成: <BodyDiv key={d._id} imgSrc={d.imgSrc} title={d.title} details={d.details} description={d.description} onClick={()=>deleteProducts(d._id)} />
2. 确保useEffect的依赖稳定
你的useEffect依赖了getProducts,虽然用connect注入的action creator一般是memoized的,但可以改用useDispatch让依赖更简洁稳定:
// 修改Body组件的导入和逻辑: import { useDispatch, useSelector } from 'react-redux'; import { getProducts, deleteProduct } from "../Features/actions/productActions"; const Body = ()=>{ const dispatch = useDispatch(); const {products, loading, error} = useSelector(state => state.productState); useEffect(()=>{ dispatch(getProducts()) },[dispatch]) // dispatch是React Redux提供的稳定引用,不会触发不必要的重复执行 // ...其他逻辑不变 } // 这样就不需要connect了,直接导出Body即可 export default Body;
这一步是可选的,但能让组件逻辑更清晰,也避免了潜在的依赖问题。
为什么加products到useEffect依赖会更糟?
如果你把products加到useEffect依赖里,会导致每次products变化时都重新调用getProducts,进而再次触发Reducer拼接数据,形成无限循环,所以情况会变得更糟——这也是为什么不能随便添加依赖的原因。
内容的提问来源于stack exchange,提问作者KR Tirtho
相关产品推荐
相关产品推荐

