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

React中点击按钮筛选API获取的商品数据的实现方法咨询

实现方案

核心逻辑

你只需要在渲染商品列表前,根据选中的筛选项对原始products数组做前端过滤,再遍历过滤后的结果渲染即可,修改成本很低,具体修改步骤如下:

步骤1:优化筛选状态管理

原来的两个布尔状态扩展性较差,我们替换为单个状态记录当前选中的商品类型,默认展示全部商品:

// 删掉原来的mugSelected、shirtSelected两个状态,替换为下面的代码
const [selectedType, setSelectedType] = useState('all'); // 可选值: all / mug / shirt

步骤2:修改筛选按钮的点击和样式逻辑

调整两个按钮的点击事件和类名判断,支持点击切换、再次点击取消筛选回到全部:

<div className="product-type-filter">
  <button 
    className={selectedType === 'mug' ? "clicked" : null} 
    onClick={() => setSelectedType(prev => prev === 'mug' ? 'all' : 'mug')}
  >
    Mug
  </button>
  <button 
    className={selectedType === 'shirt' ? "clicked" : null} 
    onClick={() => setSelectedType(prev => prev === 'shirt' ? 'all' : 'shirt')}
  >
    Shirt
  </button>
</div>

步骤3:新增商品过滤逻辑

在渲染商品列表前,新增过滤规则,得到符合条件的商品数组:

// 放在return之前即可
const filteredProducts = selectedType === 'all' 
  ? products 
  : products?.filter(product => product.itemType === selectedType) || [];

步骤4:替换渲染的数据源

把原来遍历products的代码,替换为遍历过滤后的filteredProducts:

{/* 原来的products.map改成filteredProducts.map */}
{filteredProducts.map((product) => (
  <Product key={product.added} product={product}></Product>
))}

完整修改后代码参考

import React, { useEffect, useState } from "react";
import Product from "../components/sub-components/Product";
import LoadingBox from "../components/sub-components/LoadingBox";
import MessageBox from "../components/sub-components/MessageBox";
import { useDispatch, useSelector } from "react-redux";
import { listProducts } from "../actions/productActions";
import ReactPaginate from "react-paginate";

export default function HomeScreen() {
  const dispatch = useDispatch();
  const productList = useSelector((state) => state.productList);
  const { loading, error, products } = productList;
  const [currentPage, setCurrentPage] = useState(1);
  const [pageCount, setpageCount] = useState(0);
  // 替换原筛选状态
  const [selectedType, setSelectedType] = useState('all');

  useEffect(() => {
    dispatch(listProducts(currentPage));
    // dispatch(countProducts());
  }, [dispatch, currentPage]);

  const handlePageClick = (data) => {
    setCurrentPage(data.selected + 1);
    // scroll to the top
    window.scrollTo(0, 0)
  };

  // 新增过滤逻辑
  const filteredProducts = selectedType === 'all' 
    ? products 
    : products?.filter(product => product.itemType === selectedType) || [];

  return (
    <div className="container">
      <div className="row">
        <div className="col-lg-6 col-md-12 col-sm-12 col-xs-12">
          <h2 className="title">Products</h2>
          <div className="product-type-filter">
            {/* 修改后的筛选按钮 */}
            <button 
              className={selectedType === 'mug' ? "clicked" : null} 
              onClick={() => setSelectedType(prev => prev === 'mug' ? 'all' : 'mug')}
            >
              Mug
            </button>
            <button 
              className={selectedType === 'shirt' ? "clicked" : null} 
              onClick={() => setSelectedType(prev => prev === 'shirt' ? 'all' : 'shirt')}
            >
              Shirt
            </button>
          </div>
          <div className="products">
            <div className="row">
              <div>
                {loading ? (
                  <LoadingBox></LoadingBox>
                ) : error ? (
                  <MessageBox variant="danger">{error}</MessageBox>
                ) : (
                  <div className="row center">
                    {/* 替换为过滤后的数组 */}
                    {filteredProducts.map((product) => (
                      <Product key={product.added} product={product}></Product>
                    ))}
                  </div>
                )}
              </div>
            </div>
          </div>
          <ReactPaginate
            previousLabel={"Prev"}
            nextLabel={"Next"}
            pageCount={40}
            marginPagesDisplayed={4}
            pageRangeDisplayed={1}
            onPageChange={handlePageClick}
            containerClassName={"pagination justify-content-center"}
            pageClassName={"page-item"}
            pageLinkClassName={"page-link"}
            previousClassName={"page-item"}
            previousLinkClassName={"page-link"}
            nextClassName={"page-item"}
            nextLinkClassName={"page-link"}
            breakClassName={"page-item"}
            breakLinkClassName={"page-link"}
            activeClassName={"active"}
          />
        </div>
      </div>
    </div>
  );
}

补充说明

如果你的listProducts接口是后端分页的(即每次只返回当前页的10/20条数据,不是全量商品),那么前端筛选只能过滤当前页的内容,要实现全量筛选需要把selectedType作为参数传给接口,由后端返回对应类型的分页数据即可。

内容的提问来源于stack exchange,提问作者breking bed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:39:03