You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:57:02