React Firebase onSnapshot返回空值致filtered.map报错,求解决
问题分析与修复方案
错误根源
- Filter组件重置过滤时破坏了数组类型:当
activeFilter为空时,你调用setFiltered("")把原本是数组的filtered改成了字符串,字符串没有map方法,直接触发filtered.map is not a function报错。 - activeFilter状态类型不统一:父组件初始
activeFilter是空字符串"",但All按钮点击时设置的是setActiveFilter([])(数组类型),导致按钮的active类判断永远不成立,同时状态类型混乱会引发过滤逻辑异常。 - Filter组件useEffect依赖项缺失:没有将
skins加入依赖数组,当父组件通过onSnapshot拉取到新数据时,过滤逻辑不会重新执行,导致filtered数据无法同步更新。
具体修改步骤
1. 修复过滤重置逻辑
将重置时的setFiltered("")改为setFiltered(skins),确保filtered始终是数组类型:
useEffect(() => { if (activeFilter === "") { // 重置为全部数据,保持数组类型 setFiltered(skins); return; } const filtered = skins.filter((skin) => skin.rarity.includes(activeFilter)); setFiltered(filtered); }, [activeFilter, skins]); // 补充skins依赖
2. 统一activeFilter状态类型
修改All按钮的点击事件和active类判断,保持和父组件初始状态一致的字符串类型:
<button className={activeFilter === "" ? "active" : ""} onClick={() => setActiveFilter("")} > All </button>
3. 补全useEffect依赖项
在Filter组件的useEffect依赖数组中加入skins,确保数据更新时过滤逻辑同步执行。
修改后的完整Filter组件代码
function Filter({ setActiveFilter, activeFilter, setFiltered, skins }) { useEffect(() => { if (activeFilter === "") { setFiltered(skins); return; } const filtered = skins.filter((skin) => skin.rarity.includes(activeFilter)); setFiltered(filtered); }, [activeFilter, skins]); return ( <div className="filter-container"> <button className={activeFilter === "" ? "active" : ""} onClick={() => setActiveFilter("")} > All </button> <button className={activeFilter === "Ultra" ? "active ultra" : "ultra"} onClick={() => setActiveFilter("Ultra")} > Ultra </button> <button className={ activeFilter === "Exclusive" ? "active exclusive" : "exclusive" } onClick={() => setActiveFilter("Exclusive")} > Exclusive </button> <button className={activeFilter === "Premium" ? "active premium" : "premium"} onClick={() => setActiveFilter("Premium")} > Premium </button> <button className={activeFilter === "Deluxe" ? "active deluxe" : "deluxe"} onClick={() => setActiveFilter("Deluxe")} > Deluxe </button> </div> ); }
额外说明
父组件的初始状态设置没问题(filtered初始为[]),onSnapshot触发前filtered.map遍历空数组不会报错,核心问题都集中在Filter组件的逻辑错误上,修改后即可确保filtered始终为数组类型,避免map报错。
内容的提问来源于stack exchange,提问作者Demonix
相关产品推荐
相关产品推荐

