如何在多层级对象数组中使用filter()方法?
解决多层级对象数组的filter筛选问题
首先,你的代码存在两个核心问题:useEffect的依赖数组未包含bodypart状态,导致选择变化时不会重新执行筛选逻辑;其次,筛选逻辑没有正确处理嵌套的对象结构。以下是修正后的完整方案:
修正后的React组件代码
import React, { useState, useEffect } from "react"; const tattoos = [ { head: [ { name: "1 - Crâne de pirate (H/F)", gender: "HF", price: "450" }, { name: "2 - Surf LS (H/F)", gender: "HF", price: "250" }, ], torso: [ { name: "1 - Crâne de pirate (H/F)", gender: "HF", price: "450" }, { name: "2 - Surf LS (H/F)", gender: "HF", price: "250" }, ], }, ]; export default function Searchbar() { const [filtered, setFiltered] = useState([]); const [bodypart, setBodypart] = useState("all"); function handleChange(e) { setBodypart(e.target.value); } useEffect(() => { if (bodypart === "all") { // 收集所有部位的纹身,扁平化处理 const allTattoos = tattoos.flatMap(collection => Object.values(collection).flat() ); setFiltered(allTattoos); return; } // 筛选指定部位的纹身,跨多个collection合并结果 const filteredTattoos = tattoos.flatMap(collection => collection[bodypart] || [] ); setFiltered(filteredTattoos); }, [bodypart]); // 依赖bodypart,状态变化时重新执行 return ( <div> <div> <label>身体部位:</label> <select onChange={handleChange} value={bodypart}> <option value="all">全部</option> <option value="head">头部</option> <option value="torso">躯干</option> </select> </div> {/* 示例:渲染筛选后的纹身列表 */} <div className="tattoos-list"> {filtered.map((tattoo, index) => ( <div key={index}> <h3>{tattoo.name}</h3> <p>价格: ${tattoo.price}</p> <p>适用性别: {tattoo.gender}</p> </div> ))} </div> </div> ); }
关键修正点说明
- 修复useEffect依赖:将
bodypart加入依赖数组,确保下拉选择变化时自动重新执行筛选逻辑。 - 正确处理嵌套结构:
- 当选择"all"时,用
flatMap和Object.values(collection).flat()遍历所有部位的纹身数组并扁平化,得到所有纹身的一维数组。 - 选择特定部位时,通过
collection[bodypart]直接获取对应部位的纹身数组,再用flatMap合并多个collection的结果。
- 当选择"all"时,用
- 优化select组件:添加
value={bodypart}确保下拉框显示与当前状态一致。
你之前尝试失败的原因
tattoos.filter(e => e === bodypart):e是包含head/torso的对象,和字符串比较永远为false,返回空数组。e.includes(bodypart):对象没有includes方法,直接报错。e.some(bodypart):some是数组方法,对象调用会报错。Objects.keys(e).includes(bodypart):返回的是包含该部位的collection对象数组,而非具体的纹身列表,不符合预期。
内容的提问来源于stack exchange,提问作者Nero
相关产品推荐
相关产品推荐

