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} />; }
关键优化点
- 状态逻辑简化:用
showOnlyInStock直接映射复选框状态,过滤逻辑一目了然,不会出现toggle状态混乱的问题 - 组件拆分:把过滤开关、表格、分类标题、商品行拆成独立组件,每个组件职责单一,出问题时好定位
- 逻辑提前处理:用
reduce提前按分类分组商品,避免渲染时重复计算,提升性能的同时让渲染代码更干净 - 样式直观:非库存商品的红色样式直接在
ProductItem里判断,不用额外的类名或复杂逻辑
内容的提问来源于stack exchange,提问作者guanteckkang
相关产品推荐
相关产品推荐

