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

React Redux-Toolkit:按ID获取并展示指定商品详情的问题排查

问题描述

使用React Redux-Toolkit开发商品详情功能时遇到问题:按ID获取指定商品并展示详情页时,Redux DevTools显示SingleProduct action已成功获取对应ID的商品数据,但Redux状态仍存储所有商品,导致详情页无法正常展示目标商品。请问是否需要修改ProductDetail组件?

相关代码

ProductSlice 代码

import { createSlice } from "@reduxjs/toolkit";
import { Productget,SingleProduct } from "../Action/UserAction";

const initialState=[]
const ProductSlice =createSlice(
    {
        name: "products",
        initialState,
        extraReducers:{
            [Productget.fulfilled]:(state,{payload})=>{
                return [...payload]
            },
            [SingleProduct.fulfilled]:(state,{payload})=>{
              state.find(post=>post.id === payload.id)          
            }

        }
    }
)

const {reducer} = ProductSlice;

export default reducer

ProductDetail 组件代码

import React,{useEffect,useCallback} from 'react'
import {useParams} from "react-router-dom"
import { SingleProduct } from '../Action/UserAction';
import {useDispatch, useSelector} from 'react-redux'

function ProductDetail() {
    const {productId} = useParams();
    const product = useSelector((state)=>state.products)

    console.log(product)
    const dispatch = useDispatch()

    const fetchDetails=useCallback(()=>{
        dispatch(SingleProduct({id:productId}))
    },[dispatch,productId])

    useEffect(()=>{
     fetchDetails()
    },[fetchDetails])
    
  return (

    <div className="container">
      <div className="row">
        <div className="col-md-12">
          <div className="card mt-2">
          <img src={product.image} style={{width:"300px"}} className="card-img-top mx-auto mt-3" alt="market" />
          <div className="card-body">
                            <h5 className="card-title">{product.title}</h5>
                                <p>{product.category}</p>
                                <p>{product.description}</p>
                                <div className="card-footer"> $ {product.price}</div>
                            </div>
          </div>
        </div>
      </div>
    </div>
   
  )
}

export default ProductDetail

解决方案

问题核心不在ProductDetail组件,而是ProductSlice的SingleProduct.fulfilled处理逻辑错误,没有正确更新Redux状态,以下是两种修复方案:

方案一:拆分状态结构(推荐)

将商品列表和当前详情商品分开存储,避免状态混淆:

  1. 修改ProductSlice的初始状态和reducer逻辑:
const initialState = {
  list: [],
  current: null
}

const ProductSlice = createSlice({
  name: "products",
  initialState,
  extraReducers: {
    [Productget.fulfilled]: (state, { payload }) => {
      state.list = [...payload];
    },
    [SingleProduct.fulfilled]: (state, { payload }) => {
      state.current = payload; // 直接存储当前获取的单个商品
    }
  }
})
  1. 修改ProductDetail组件的状态获取:
const product = useSelector((state) => state.products.current)

方案二:保留列表状态,组件内筛选

如果不想修改状态结构,可直接在组件中从列表筛选目标商品:

  1. 先修复ProductSlice的SingleProduct逻辑(确保列表数据正确更新):
[SingleProduct.fulfilled]: (state, { payload }) => {
  const index = state.findIndex(post => post.id === payload.id);
  if (index !== -1) {
    state[index] = payload; // 更新已有商品数据
  } else {
    state.push(payload); // 列表无此商品则添加
  }
}
  1. 修改ProductDetail组件的状态获取:
const products = useSelector((state) => state.products)
const product = products.find(item => item.id === productId)

组件额外优化

由于product可能为null或undefined,渲染时需做空值判断避免报错:

return (
  <div className="container">
    {product ? (
      <div className="row">
        <div className="col-md-12">
          <div className="card mt-2">
            <img src={product.image} style={{width:"300px"}} className="card-img-top mx-auto mt-3" alt="market" />
            <div className="card-body">
              <h5 className="card-title">{product.title}</h5>
              <p>{product.category}</p>
              <p>{product.description}</p>
              <div className="card-footer"> $ {product.price}</div>
            </div>
          </div>
        </div>
      </div>
    ) : (
      <div>加载中...</div>
    )}
  </div>
)

内容的提问来源于stack exchange,提问作者aiffin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:55:10