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

React组件问题:点击'All'按钮无法渲染全部产品

解决React中点击'All'分类按钮无法显示全部产品的问题

问题代码中的核心错误

  1. Categories组件点击判断逻辑错误
    • 原代码用categories === "All"将整个分类数组与字符串比较,实际应该判断当前遍历的item === "All"
    • 点击'All'时仅返回prepareData函数,未执行调用,需改为prepareData()
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:10:29