React组件问题:点击'All'按钮无法渲染全部产品
解决React中点击'All'分类按钮无法显示全部产品的问题
问题代码中的核心错误
- Categories组件点击判断逻辑错误
- 原代码用
categories === "All"将整个分类数组与字符串比较,实际应该判断当前遍历的item === "All" - 点击'All'时仅返回
prepareData函数,未执行调用,需改为prepareData()
- 原代码用
- Products组件数据处理逻辑错误
prepareData函数中错误地在filter === "all"时执行setFilter(products),将filter从分类字符串改为产品数组,导致后续过滤逻辑失效prepareData的作用应为根据filter返回对应产品,而非修改filter状态
修正后的代码
Categories组件
import React, { useEffect, useState } from "react"; import NavBar from "../NavBar"; import "./Categories.css"; function Categories({ prepareData, handleFilter }) { const [categories, setCategories] = useState(["All"]); useEffect(() => { fetch(`https://dummyjson.com/products/categories/`) .then((req) => req.json()) .then((res) => { // 使用函数式更新避免闭包问题 setCategories(prev => [...prev, ...res]); }); }, []); return ( <> <NavBar /> <div className="categoriesContainer"> {categories.map((item, index) => { return ( <div key={index} className="singleCategoryContainer" onClick={() => item === "All" ? prepareData() : handleFilter(item) } > {item} </div> ); })} </div> </> ); } export default Categories;
Products组件
import React, { useState, useEffect } from "react"; import Categories from "../components/Categories/Categories"; import SingleProduct from "./SingleProduct"; import "./Products.css"; function Products() { const [products, setProducts] = useState([]); const [filter, setFilter] = useState("all"); useEffect(() => { fetch("https://dummyjson.com/products?limit=100") .then((req) => req.json()) .then((res) => setProducts(res.products)); }, []); const handleFilter = (data) => { setFilter(data); }; const prepareData = () => { // 兼容"all"和"All"两种状态值,返回对应产品 if (filter === "all" || filter === "All") { return products; } return products.filter((item) => item.category === filter); }; if (products.length === 0) { return <div className="loader">Loading...</div>; } return ( <> <Categories prepareData={prepareData} handleFilter={handleFilter} /> <div className="productsContainer"> {prepareData().map((item, index) => { return ( <div key={index} className="singleProductContainer"> <SingleProduct data={item} /> </div> ); })} </div> </> ); } export default Products;
额外优化说明
- 用函数式更新
setCategories(prev => [...prev, ...res])避免初始闭包导致的分类数组更新异常 - 兼容
filter的"all"和"All"两种值,确保点击'All'按钮时逻辑统一 - 移除了错误的状态修改操作,保证
filter始终存储分类字符串,维持状态一致性
内容的提问来源于stack exchange,提问作者Bogdan Dimitrievski
相关产品推荐
相关产品推荐

