Firebase 9+React18中Sidebar.jsx出现map读取undefined错误求助
解决Firebase 9 + React 18中TypeError: Cannot read properties of undefined (reading 'map')的问题
错误详情
Sidebar.jsx:20 Uncaught TypeError: Cannot read properties of undefined (reading 'map')
问题根源
- 异步操作未正确处理:
getDocs是异步函数,返回的是Promise对象而非直接的查询快照。直接访问roomsRef.docs时,roomsRef还处于Pending状态,此时docs属性不存在,导致undefined报错。 - 数据访问路径错误:映射rooms时写了
room.data.name,但{ id: doc.id, ...doc.data() }已经把文档数据展开到了room对象中,正确访问方式应为room.name。
修复方案
1. 正确处理Firestore异步请求
在useEffect中用async/await处理getDocs的异步结果
2. 修正数据访问路径
将room.data.name改为room.name
修改后的Sidebar.jsx代码
import React, { useState, useEffect } from 'react' import './Sidebar.css' import { Avatar, IconButton } from '@mui/material'; import DonutLargeOutlinedIcon from '@mui/icons-material/DonutLargeOutlined'; import InsertCommentIcon from '@mui/icons-material/InsertComment'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined'; import SidebarChat from '../SidebarChat/SidebarChat'; import db from '../../firebase' import { collection, getDocs } from "firebase/firestore" const Sidebar = () => { const [rooms, setRooms] = useState([]) useEffect(() => { const fetchRooms = async () => { const roomsCollection = collection(db, "rooms") const snapshot = await getDocs(roomsCollection) setRooms(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))) } fetchRooms() }, []) return ( <div className='sidebar'> <div className="sidebar__header"> <Avatar src="/broken-image.jpg" /> <div className="sidebar__headerRight"> <IconButton> <DonutLargeOutlinedIcon /> </IconButton> <IconButton> <InsertCommentIcon /> </IconButton> <IconButton> <MoreVertIcon /> </IconButton> </div> </div> <div className="sidebar__search"> <div className="sidebar__searchContainer"> <SearchOutlinedIcon /> <input type="text" placeholder='Serach or start a new chat' /> </div> </div> <div className="sidebar__chat"> <SidebarChat addNewChat /> {rooms.map(room => ( <SidebarChat key={room.id} id={room.id} name={room.name} /> ))} </div> </div> ) } export default Sidebar
额外建议
可以添加错误处理逻辑,避免请求失败导致页面异常:
const fetchRooms = async () => { try { const roomsCollection = collection(db, "rooms") const snapshot = await getDocs(roomsCollection) setRooms(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))) } catch (err) { console.error('获取房间数据失败:', err) } }
内容的提问来源于stack exchange,提问作者Pavitar Sharma
相关产品推荐
相关产品推荐

