React中如何遍历Firestore返回对象,获取数字键内容并解决map报错问题
报错原因
你遇到的报错核心原因是:user["1"].items是普通对象类型,而map是仅数组可用的方法,直接对对象调用map会触发类型错误。
另外你将Firestore返回的单条用户数据包裹进了数组存入users状态,使用时需要先取出数组第一项才是目标用户对象,否则也可能出现取不到值的情况。
解决方法
方式1:遍历items对象的所有属性
如果你需要展示items下所有项,可以先通过Object.entries()将对象转为键值对数组再遍历:
// 先从users数组取出目标用户数据 const user = users[0] // 渲染key为1的items下所有内容 {user?.["1"]?.items && Object.entries(user["1"].items).map(([itemKey, itemValue]) => ( <li key={itemKey}>{itemKey}: {itemValue ? '已选中' : '未选中'}</li> ))}
方式2:直接取指定属性
如果你只需要获取Item1的固定值,不需要遍历,直接取值即可:
const user = users[0] {user?.["1"]?.items?.Item1 && <li>Item1: 已选中</li>}
方式3:遍历所有数字键(1、2)的内容
如果你需要把所有数字为键的分组都渲染出来,可以参考如下代码:
const user = users[0] // 筛选出所有数字类型的键 const groupKeys = Object.keys(user).filter(key => !isNaN(Number(key))) return ( <div> {groupKeys.map(groupKey => ( <div key={groupKey}> <h3>分组{groupKey}(分类:{user[groupKey].others})</h3> <ul> {Object.entries(user[groupKey].items).map(([itemName, status]) => ( <li key={itemName}>{itemName}: {status ? '已勾选' : '未勾选'}</li> ))} </ul> </div> ))} </div> )
优化建议
因为每个uid对应的用户数据只有1条,不需要包裹成数组存储,可以直接修改useEffect里的赋值逻辑,后续使用更方便:
useEffect(() => { if (currentUser) { const unsubscribe = db .collection("users") .doc(uid) .onSnapshot((snapshot) => { // 直接存对象,不用包数组 setUsers(snapshot.data()); }); return () => unsubscribe(); } }, [currentUser])
修改后使用时不需要再取users[0],直接users?.["1"]就能取到对应内容。
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

