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

React复选框过滤功能实现问题及代码优化求助

React商品过滤与代码优化方案

一、修复过滤逻辑

  • 用useState定义showOnlyInStock状态,初始值设为false(默认显示所有商品)
  • 复选框的onChange事件直接绑定状态切换,不用复杂的toggle逻辑:
    <input 
      type="checkbox" 
      checked={showOnlyInStock} 
      onChange={(e) => setShowOnlyInStock(e.target.checked)} 
    />
    
  • 渲染商品前根据状态过滤列表:如果勾选了“只显示库存商品”,就保留stocked: true的项,否则展示全部

二、代码简化与可读性提升

核心思路是拆分组件,让每个组件只做一件事,同时把重复逻辑提取出来:

示例完整代码

import { useState, Fragment } from 'react';

// 模拟商品数据
const PRODUCTS = [
  { category: '电子产品', price: '$99', stocked: true, name: '智能手机' },
  { category: '电子产品', price: '$199', stocked: false, name: '平板电脑' },
  { category: '家居用品', price: '$49', stocked: true, name: 'LED台灯' },
  { category: '家居用品', price: '$29', stocked: false, name: '棉麻抱枕' },
];

// 主组件:统筹过滤状态和商品展示
function FilterableProductTable({ products }) {
  const [showOnlyInStock, setShowOnlyInStock] = useState(false);
  
  // 过滤逻辑直接写在渲染前,清晰直观
  const filteredProducts = showOnlyInStock 
    ? products.filter(item => item.stocked) 
    : products;

  return (
    <div style={{ width: '400px', margin: '20px auto' }}>
      <FilterSwitch 
        checked={showOnlyInStock} 
        onToggle={setShowOnlyInStock} 
      />
      <ProductTable products={filteredProducts} />
    </div>
  );
}

// 过滤开关组件:只负责渲染复选框和状态切换
function FilterSwitch({ checked, onToggle }) {
  return (
    <label style={{ display: 'block', marginBottom: '10px' }}>
      <input 
        type="checkbox" 
        checked={checked} 
        onChange={(e) => onToggle(e.target.checked)} 
      />
      只显示有库存的商品
    </label>
  );
}

// 商品表格组件:负责按分类渲染商品列表
function ProductTable({ products }) {
  // 提前按分类分组,避免渲染时重复计算
  const groupedByCategory = products.reduce((groups, item) => {
    const cat = item.category;
    groups[cat] = groups[cat] || [];
    groups[cat].push(item);
    return groups;
  }, {});

  return (
    <table border="1" cellPadding="8" width="100%">
      <thead>
        <tr>
          <th>商品名称</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        {Object.entries(groupedByCategory).map(([category, items]) => (
          <Fragment key={category}>
            <CategoryHeader name={category} />
            {items.map(item => <ProductItem key={item.name} data={item} />)}
          </Fragment>
        ))}
      </tbody>
    </table>
  );
}

// 分类标题组件:只负责渲染分类表头
function CategoryHeader({ name }) {
  return (
    <tr>
      <th colSpan="2" style={{ backgroundColor: '#f5f5f5' }}>
        {name}
      </th>
    </tr>
  );
}

// 单个商品组件:负责渲染商品行和非库存红色样式
function ProductItem({ data }) {
  return (
    <tr>
      <td style={{ color: data.stocked ? 'inherit' : 'red' }}>
        {data.name}
      </td>
      <td>{data.price}</td>
    </tr>
  );
}

// 渲染主组件
export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}

关键优化点

  1. 状态逻辑简化:用showOnlyInStock直接映射复选框状态,过滤逻辑一目了然,不会出现toggle状态混乱的问题
  2. 组件拆分:把过滤开关、表格、分类标题、商品行拆成独立组件,每个组件职责单一,出问题时好定位
  3. 逻辑提前处理:用reduce提前按分类分组商品,避免渲染时重复计算,提升性能的同时让渲染代码更干净
  4. 样式直观:非库存商品的红色样式直接在ProductItem里判断,不用额外的类名或复杂逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:54:24