ReactJS中按类别筛选API返回商品列表的问题求助
React 商品分类筛选功能修复
现存问题梳理
- API响应未正确解析:
fetch返回的是Response对象,直接存入newProduct会导致后续filter操作无法执行,必须调用.json()解析返回数据。 - 请求接口错误:当前请求的是分类列表接口(
/api/categories/),而非商品列表接口,且未根据筛选条件传递查询参数。 - 筛选逻辑存在死代码:
filter函数开头的return product.category === filterList;会直接终止函数,后面的if判断永远不会执行。 - "all"选项逻辑错误:当前
else分支返回false,选中"all"时会过滤掉所有商品,正确逻辑应返回true以展示全部商品。 - 初始状态与异步加载未处理:
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;
关键改动说明
API请求修正:
- 改为请求商品列表接口(需根据实际API地址调整)
- 根据
filterList动态拼接查询参数,支持后端筛选 - 增加加载、错误状态处理,提升用户体验
- 正确解析
Response为JSON数据后存入状态
筛选逻辑修正:
- 移除导致死代码的前置
return语句 - "all"选项返回
true,确保展示全部商品 - 提供两种筛选逻辑选项,根据API返回的商品结构选择对应方式
- 移除导致死代码的前置
状态管理优化:
- 初始化
newProduct为空数组,避免filter时的undefined错误 - 增加
loading和error状态,处理异步加载过程中的各种情况
- 初始化
内容的提问来源于stack exchange,提问作者Hazal Kaya
相关产品推荐
相关产品推荐

