You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:01:12