Redux存储产品后无法在React组件中渲染问题求助
问题分析与解决
你的代码存在几个关键问题,导致产品无法正常渲染:
1. useEffect无限循环
useEffect的依赖数组里包含了product,每次调用setProduct更新product时,都会触发useEffect重新执行,进而再次调用fetchProduct,形成无限循环,直接导致应用卡顿甚至崩溃。
2. 冗余的本地State
你已经把产品数据存在Redux的currProduct中,但组件却额外用本地useState存储产品,完全没必要。而且await dispatch(getProduct(id))返回的是action对象,虽然能拿到response.payload,但正确的做法是直接从Redux store读取数据,而非用本地state同步。
3. loading状态未定义
组件里的loading变量没有声明,应该从Redux store的state.loading中读取,而非使用未定义的变量。
4. productsSlice语法错误
你的productsSlice代码片段结构错误,builder.addCase应该放在createSlice的extraReducers配置项中,不能直接跟在createAsyncThunk后面。
修正后的代码
ProductDetails.jsx
import { useDispatch, useSelector } from 'react-redux'; import { getProduct } from './productsSlice'; import { useParams, useEffect } from 'react'; import ClipLoader from 'react-spinners/ClipLoader'; const ProductDetails = () => { const dispatch = useDispatch(); const { id } = useParams(); // 直接从Redux store读取数据和loading状态 const { currProduct, loading } = useSelector(state => state.products); useEffect(() => { dispatch(getProduct(id)); }, [id, dispatch]); return ( <div className="details-container"> {loading || !currProduct ? ( <ClipLoader color="#36d7b7" loading={loading} size={35} /> ) : ( <div className="img-container"> <img src={currProduct.img} alt={currProduct.brand} /> </div> )} </div> ); }; export default ProductDetails;
productsSlice.jsx
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import productsService from './productsService'; export const getProduct = createAsyncThunk("products/getProduct", async (id) => { const prod = await productsService.getProductById(id); return prod; }); const productsSlice = createSlice({ name: 'products', initialState: { loading: true, // 初始设置为加载状态 currProduct: null, error: '' }, extraReducers: (builder) => { builder .addCase(getProduct.pending, (state) => { state.loading = true; }) .addCase(getProduct.fulfilled, (state, action) => { state.loading = false; state.currProduct = action.payload; state.error = ''; }) .addCase(getProduct.rejected, (state, action) => { state.loading = false; state.currProduct = null; state.error = action.error.message || '获取产品失败'; }); } }); export default productsSlice.reducer;
关键修改说明
- 移除本地
useState,通过useSelector直接从Redux store获取currProduct和loading状态 - 简化
useEffect依赖项,只保留id和dispatch,彻底解决无限循环问题 - 完善
productsSlice的状态处理逻辑,补充pending和rejected状态的处理,确保loading状态正确更新 - 组件中同时判断
loading和currProduct,避免初始状态下的错误渲染
内容的提问来源于stack exchange,提问作者Amit Amar
相关产品推荐
相关产品推荐

