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

ReactJS中按类别筛选API返回商品列表的问题求助

React 商品分类筛选功能修复

现存问题梳理

  1. API响应未正确解析:fetch返回的是Response对象,直接存入newProduct会导致后续filter操作无法执行,必须调用.json()解析返回数据。
  2. 请求接口错误:当前请求的是分类列表接口(/api/categories/),而非商品列表接口,且未根据筛选条件传递查询参数。
  3. 筛选逻辑存在死代码:filter函数开头的return product.category === filterList;会直接终止函数,后面的if判断永远不会执行。
  4. "all"选项逻辑错误:当前else分支返回false,选中"all"时会过滤掉所有商品,正确逻辑应返回true以展示全部商品。
  5. 初始状态与异步加载未处理:newProduct初始值设为products,但useEffect触发后会被覆盖,且未处理API加载中的状态,容易出现undefined错误。

修正后的完整代码

import { useState, useEffect } from 'react';

const ProductFilterComponent = () => {
  const [filterList, setFilterList] = useState("all");
  const [newProduct, setNewProduct] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  // 按分类筛选商品的API请求逻辑
  useEffect(() => {
    let isValidScope = true;

    const fetchFilteredProducts = async () => {
      setLoading(true);
      setError(null);
      try {
        // 构造请求URL:如果是all则请求全部商品,否则按分类筛选
        let url = "https://myapi-api.herokuapp.com/api/products/";
        if (filterList !== "all") {
          url = `${url}?category=${filterList}`;
          // 如果API是按布尔字段匹配(比如product.electronics为true),则替换为:
          // url = `${url}?${filterList}=true`;
        }

        const res = await fetch(url, {
          method: "GET",
          headers: {
            Authorization: `Bearer ${accessToken}`,
            "Content-Type": "application/json",
          },
        });

        if (!res.ok) throw new Error('请求失败');
        const data = await res.json();

        if (isValidScope) {
          setNewProduct(data);
        }
      } catch (err) {
        if (isValidScope) {
          setError(err.message);
        }
      } finally {
        if (isValidScope) {
          setLoading(false);
        }
      }
    };

    fetchFilteredProducts();

    return () => {
      isValidScope = false;
    };
  }, [filterList, accessToken]);

  // 筛选值变更回调
  function onFilterValueSelected(filterValue) {
    setFilterList(filterValue);
  }

  // 本地筛选逻辑(如果API不支持筛选,改用本地过滤)
  let filteredProductList;
  if (loading) {
    filteredProductList = <div>加载中...</div>;
  } else if (error) {
    filteredProductList = <div>错误:{error}</div>;
  } else {
    filteredProductList = newProduct.filter((product) => {
      if (filterList === "all") {
        return true; // 展示全部商品
      }
      // 二选一:根据product的category字段匹配,或根据布尔字段匹配
      // 选项1:如果商品有category字段
      return product.category === filterList;
      // 选项2:如果商品是按布尔字段标记分类(比如product.electronics=true)
      // return product[filterList] === true;
    });
  }

  // 渲染部分(示例)
  return (
    <div>
      <div className="filters">
        <button onClick={() => onFilterValueSelected("all")}>全部</button>
        <button onClick={() => onFilterValueSelected("electronics")}>电子产品</button>
        <button onClick={() => onFilterValueSelected("clothing")}>服装</button>
        <button onClick={() => onFilterValueSelected("accsessories")}>配饰</button>
        <button onClick={() => onFilterValueSelected("furniture")}>家具</button>
        <button onClick={() => onFilterValueSelected("hobby")}>爱好用品</button>
      </div>
      <div className="product-list">
        {Array.isArray(filteredProductList) ? (
          filteredProductList.map(product => (
            <div key={product.id}>{product.name}</div>
          ))
        ) : (
          filteredProductList
        )}
      </div>
    </div>
  );
};

export default ProductFilterComponent;

关键改动说明

  1. API请求修正:

    • 改为请求商品列表接口(需根据实际API地址调整)
    • 根据filterList动态拼接查询参数,支持后端筛选
    • 增加加载、错误状态处理,提升用户体验
    • 正确解析Response为JSON数据后存入状态
  2. 筛选逻辑修正:

    • 移除导致死代码的前置return语句
    • "all"选项返回true,确保展示全部商品
    • 提供两种筛选逻辑选项,根据API返回的商品结构选择对应方式
  3. 状态管理优化:

    • 初始化newProduct为空数组,避免filter时的undefined错误
    • 增加loading和error状态,处理异步加载过程中的各种情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:40:24