在React中如何从Firestore集合的多文档中获取单个文档ID
解决Firestore查看特定文档时仅获取当前文档ID的问题
问题分析
你当前的代码将集合中所有文档的ID都存储到了fetch状态,所以点击查看时自然会拿到全部ID数组。要实现仅获取当前查看文档的ID,核心是在触发查看操作时,直接绑定或获取单个文档的ID,而非提前存储所有ID。
解决方案
方案1:点击列表项时直接获取当前文档ID(最常用场景)
删除原代码中setFetch(tasksData.map(task => task.id))这一行(无需存储所有ID),然后在渲染文档列表时,给每个项绑定点击事件,直接传递当前文档的ID:
// 保留获取tasks的逻辑,移除setFetch相关代码 const collectionRef = collection(db, "mcsSystems/" + userId , "reportmcs") useEffect(()=>{ const getTasks = async () => { const q = query(collectionRef) try { const taskSnapshot = await getDocs(q) const tasksData = taskSnapshot.docs.map(doc => ({...doc.data(), id: doc.id})) setTasks(tasksData) console.log("tasksData", tasksData) } catch (err) { console.log(err) } } getTasks() }, []) // 新增点击处理函数 const handleViewDocument = (currentDocId) => { // currentDocId即为当前查看的单个文档ID console.log("当前查看的文档ID:", currentDocId) // 可将ID存入状态供后续使用 // setCultureId(currentDocId) } // 渲染文档列表时绑定点击事件 return ( <div> {tasks.map(task => ( <div key={task.id} onClick={() => handleViewDocument(task.id)}> {/* 渲染文档内容,例如task.title、task.content等 */} {task.name} </div> ))} </div> )
方案2:通过路由参数获取文档ID(适用于单独详情页)
如果项目使用路由(如React Router),可在跳转到详情页时把文档ID作为路由参数传递,再在详情页直接读取该参数:
1. 列表页跳转时传递ID
import { useNavigate } from 'react-router-dom'; const navigate = useNavigate(); const handleGoToDetail = (currentDocId) => { navigate(`/document-detail/${currentDocId}`) }
2. 详情页读取路由参数并获取文档
import { useParams } from 'react-router-dom'; import { doc, getDoc } from "firebase/firestore"; const DocumentDetail = ({ userId }) => { const { docId } = useParams(); // 读取路由中的文档ID const [currentDoc, setCurrentDoc] = useState(null); useEffect(() => { if (docId && userId) { const getSingleDocument = async () => { const docRef = doc(db, "mcsSystems/" + userId, "reportmcs", docId); const docSnap = await getDoc(docRef); if (docSnap.exists()) { setCurrentDoc({...docSnap.data(), id: docSnap.id}) console.log("当前文档ID:", docId) } else { console.log("未找到该文档") } } getSingleDocument() } }, [docId, userId]) return ( <div> {currentDoc && ( <div> <h3>文档ID:{currentDoc.id}</h3> {/* 渲染文档详情内容 */} </div> )} </div> ) }
内容的提问来源于stack exchange,提问作者Deezy
相关产品推荐
相关产品推荐

