通过另一映射数组的索引展示对象数组元素时遇类型错误
错误原因与解决方案
核心错误点
你代码里的venues[0].map是触发错误的直接原因:venues是对象数组,venues[0]是单个对象(比如{id:4, title:"bro"}),而map是数组的专属方法,对象没有这个方法,因此会抛出TypeError: ...map is not a function。
另外你已经通过findIndex拿到了对应id的索引,但完全没用到这个索引,反而硬写venues[0],完全偏离了「根据cityArray里的id匹配对应venue」的需求逻辑。
修正后的代码
下面是调整后的完整组件代码,重点修复了渲染逻辑,同时补充了空值处理和React列表要求的key:
import { useState, useEffect, useMemo } from 'react'; import { useParams, useDispatch, useSelector } from 'react-redux'; const Home = () => { const { city } = useParams(); const dispatch = useDispatch(); const featured = useSelector((state) => state.featuredList.featured); const venues = useSelector((state) => state.venueList.venues); const [cityArray, setCityArray] = useState([]); useEffect(() => { dispatch(listVenues()); }, [dispatch]); useEffect(() => { dispatch(listFeatured()); }, [dispatch]); useEffect(() => { if (city === "perth") { setCityArray(featured?.featured_perth || []); } }, [featured, city]); // 优化:将venues转为id映射的对象,提升查找性能 const venueMap = useMemo(() => { return Object.fromEntries(venues.map(v => [parseInt(v.id), v])); }, [venues]); return ( <GridWrapper> {/* 处理venues加载中的状态 */} {!venues.length ? ( <div>场馆数据加载中...</div> ) : ( cityArray?.map((venueId, idx) => { const matchedVenue = venueMap[parseInt(venueId)]; // 找不到匹配项时返回null,避免渲染错误 if (!matchedVenue) return null; return ( <div key={`${matchedVenue.id}-${idx}`}> <h1>{matchedVenue.title}</h1> </div> ); }) )} </GridWrapper> ); }; export default Home;
关键调整说明
- 补上缺失的基础hooks:原代码漏了
useDispatch和useState的调用,这是React组件运行的必要逻辑。 - 替换错误的map调用:直接根据
cityArray中的id找到对应venue对象,不再错误地对单个对象调用map。 - 空值与加载状态处理:
- 给
setCityArray设置默认空数组,避免cityArray为undefined - 增加
venues为空时的加载提示,提升用户体验
- 给
- 性能优化:用
useMemo生成venueMap,把数组查找从O(n)优化为O(1),适合数据量大的场景。 - 合规的列表key:用
venue.id + idx作为key,避免因cityArray中重复id导致的React渲染警告。
内容的提问来源于stack exchange,提问作者Samm Ratan
相关产品推荐
相关产品推荐

