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

React Redux Toolkit(RTK)动态分类实现及报错解决

解决方案

问题根源

组件初始化时,useGetSingleProductQuery 还处于请求状态,getSingleProduct 是 undefined,所以 useState(getSingleProduct?.category) 的初始值为 undefined。而JSX中通过 isFetching 和 error 的判断,只有当请求完成、数据加载成功后才会渲染包含 getSingleProduct.category 的内容,这时候 getSingleProduct 已经有有效值,所以能正常访问。

另外你当前的 useEffect 依赖为空数组,只会执行一次,且执行时 url 中的 matchCategory 是初始的 undefined,导致请求无效,后续也不会重新触发请求。

优化方案(基于RTK Query实现)

既然已经用了Redux Toolkit和RTK Query,完全不需要混用axios,直接利用已定义的 useGetRelatedProductQuery 来实现相关商品获取,逻辑更简洁且符合RTK Query的设计规范:

修改后的完整代码

import React from "react";
import {
  useGetSingleProductQuery,
  useGetRelatedProductQuery,
} from "../../features/productsApi";
import { useParams } from "react-router-dom";

function ProductDetails() {
  const { id } = useParams();

  // 获取单个商品数据
  const {
    data: getSingleProduct,
    isFetching: isSingleFetching,
    error: singleError,
  } = useGetSingleProductQuery(id);

  // 获取同分类商品:当getSingleProduct存在时才发起请求,避免参数为空
  const {
    data: relatedProducts,
    isFetching: isRelatedFetching,
    error: relatedError,
  } = useGetRelatedProductQuery(getSingleProduct?.category, {
    skip: !getSingleProduct, // 商品数据未加载时跳过请求
  });

  if (isSingleFetching) return <p>Loading product details...</p>;
  if (singleError) return <p>Failed to load product details</p>;

  return (
    <div className="row mt-5">
      {/* 商品详情区域 */}
      <div className="col-md-6 mb-5 text-center">
        <img
          className="w-100"
          style={{ height: "300px", objectFit: "contain" }}
          src={getSingleProduct.image}
          alt={getSingleProduct.title}
        />
        <div>{getSingleProduct.title.substring(0, 20)}</div>
        <p>{getSingleProduct.description}</p>
        <p>Category: {getSingleProduct.category}</p>
      </div>

      {/* 相关商品区域 */}
      <div className="col-md-6">
        <h3>Related Products</h3>
        {isRelatedFetching ? (
          <p>Loading related products...</p>
        ) : relatedError ? (
          <p>Failed to load related products</p>
        ) : (
          <div className="row">
            {relatedProducts?.map(product => (
              <div key={product.id} className="col-md-6 mb-3">
                <img
                  className="w-100"
                  style={{ height: "150px", objectFit: "contain" }}
                  src={product.image}
                  alt={product.title}
                />
                <p>{product.title.substring(0, 15)}</p>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

export default ProductDetails;

关键修改点

  • 移除了多余的 useState 和 axios 请求,完全用RTK Query的hook管理数据请求
  • 使用 useGetRelatedProductQuery 的 skip 选项,确保只有当单个商品数据加载完成后才发起相关商品请求
  • 拆分了加载状态和错误状态,分别处理商品详情和相关商品的加载/错误情况
  • 优化了JSX结构,清晰区分商品详情和相关商品展示区域

补充说明

如果你的 useGetRelatedProductQuery 还没有配置正确的请求参数,需要在 productsApi 中确保它的查询参数是分类名称,比如:

// 在features/productsApi.js中定义相关商品的查询
export const productsApi = createApi({
  reducerPath: 'productsApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:5000/' }),
  endpoints: (builder) => ({
    // ...其他接口
    getRelatedProduct: builder.query({
      query: (category) => `products?category=${category}`,
    }),
  }),
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:40:28