React中如何通过按钮过滤数组映射的项目列表?
问题分析与解决方案
你的核心问题在于使用了单个布尔值状态active来控制所有项目的显示,这显然无法区分不同分类的项目。当你遍历项目列表时,每次设置active都会覆盖之前的值,最终所有项目都会使用最后一次设置的状态,导致全部显示或隐藏。
以下是修正后的实现方案:
修正后的代码(ProjectItem.jsx)
import React, { useState } from "react" import { Link } from "gatsby" import { ProjectsList } from "./data"; export default function ProjectItem() { // 用状态跟踪当前选中的分类,初始值null表示显示所有项目 const [selectedCategory, setSelectedCategory] = useState(null); return ( <> <h2>Projects</h2> <div className="double-buttons spacer-4"> <button className={`button ${selectedCategory === 'print' ? 'active-btn' : ''}`} onClick={() => setSelectedCategory('print')}> Print Button </button> <button className={`button ${selectedCategory === 'digital' ? 'active-btn' : ''}`} onClick={() => setSelectedCategory('digital')}> Digital Button </button> {/* 可选:添加"全部"按钮重置筛选 */} <button className={`button ${selectedCategory === null ? 'active-btn' : ''}`} onClick={() => setSelectedCategory(null)}> All Projects </button> </div> <div className="grid--col-4" id="projectsSection"> {/* 先筛选再映射,只渲染匹配分类的项目 */} {ProjectsList .filter(item => !selectedCategory || item.category === selectedCategory) .map((item, i) => ( <Link to={item.path} className='project-tile active' key={i}> <div className="grid__cell"> <img src={item.backgroundUrl} alt={item.title} /> <div className="grid__cell__title"> <h4>{item.title}</h4> </div> </div> </Link> )) } </div> </> ) }
关键修改说明
- 状态变更:将
active布尔状态改为selectedCategory字符串状态,用于存储当前选中的分类(print/digital/null) - 简化点击逻辑:直接在按钮的
onClick中设置选中分类,无需遍历项目列表 - 筛选渲染:通过
filter方法先过滤出匹配分类的项目,再进行映射渲染,避免DOM中保留隐藏元素 - 按钮状态反馈:为当前选中的按钮添加
active-btn类(需自行定义CSS样式),提升用户体验
额外优化建议
- 移除
index.jsx中无用的active状态,因为筛选逻辑完全在ProjectItem组件内处理 - 如果需要保留所有项目在DOM中(仅通过CSS隐藏),可以将
filter改为在映射时判断:{ProjectsList.map((item, i) => ( <Link to={item.path} className={!selectedCategory || item.category === selectedCategory ? 'project-tile active' : 'project-tile hidden'} key={i}> {/* ... */} </Link> ))}
内容的提问来源于stack exchange,提问作者Connor
相关产品推荐
相关产品推荐

