React结合Firebase删除文档时获取错误document ID的问题咨询
问题根因
- 你在
posts.map遍历渲染每篇帖子时,都单独生成了一个Modal组件,但所有Modal共用同一个全局open状态。点击任意删除按钮会触发所有Modal同时设为打开状态,最终页面只会渲染遍历到的最后一篇帖子对应的Modal,因此handleDelete永远拿到最后一篇帖子的ID - 你定义的
handleOpen预留了id入参,但实际调用时没有传入当前帖子的ID,也没有单独的状态存储当前待删除的帖子ID
修复方案
我们只需要全局保留一个Modal,新增状态存储待删除的帖子ID即可,修改后的完整代码如下:
import React, { useState } from "react"; import { projectFirestore } from "../../../../firebase/config"; import { useCollectionData } from "react-firebase-hooks/firestore"; import Layout from "../../../../hoc/Layout/Layout"; import { Link } from "react-router-dom"; import { Button, Box, Modal } from "@mui/material"; const DeletePost = () => { const docRef = projectFirestore.collection("News"); const query = docRef.orderBy("createdAt", "desc"); const [posts] = useCollectionData(query, { idField: "id" }); // Modal operations 新增selectedPostId存储待删除的帖子ID const [open, setOpen] = useState(false); const [selectedPostId, setSelectedPostId] = useState(null); // 打开Modal时存入当前点击的帖子ID const handleOpen = (id) => { setSelectedPostId(id); setOpen(true); }; const handleClose = () => { setSelectedPostId(null); setOpen(false); }; const handleDelete = () => { const docRef = projectFirestore.collection("News").doc(selectedPostId); docRef.delete(); console.log("Deleted post data from id: " + selectedPostId); handleClose(); }; // 找到当前选中的帖子用于Modal展示 const selectedPost = posts?.find(post => post.id === selectedPostId); return ( <Layout> <ul> {posts && posts.map((post) => { const data = post.createdAt.toDate(); const day = data.getUTCDate(); const month = data.getUTCMonth(); const year = data.getUTCFullYear(); return ( <li key={post.id}> <div> <h3>{post.id}</h3> <img src={post.url} alt={post.title} /> <p> <b> {day}/{month}/{year} </b>{" "} {post.description} </p> </div> <div> <Link to="/edit-post"> <Button> Edit Post </Button> </Link> {/* 调用handleOpen时传入当前帖子ID */} <Button onClick={() => handleOpen(post.id)}> Delete Post </Button> </div> </li> ); })} </ul> {/* Modal从循环里移出来,全局只渲染一个 */} {selectedPost && ( <Modal open={open} onClose={handleClose} aria-labelledby="Delete" aria-describedby="Delete Post" > <Box> <div> <h4> Are you sure you want to delete {selectedPost.title}? </h4> </div> <div> <Button onClick={handleDelete}> Yes </Button> <Button onClick={handleClose}> No </Button> </div> </Box> </Modal> )} </Layout> ); }; export default DeletePost;
内容的提问来源于stack exchange,提问作者Rui Castro
相关产品推荐
相关产品推荐

