在 React + Firebase 中,如何删除在创建时已被赋予唯一 ID 的列表项?

How do I delete a list item that has been given a unique id when created, in React + Firebase?

我正在使用 React 和 Firebase 创建待办事项列表。到目前为止,我已经创建了 AddToDo 功能,但是,现在我在使用删除功能时遇到了问题。我相信这就是我的问题所在。例如,当我尝试单击我设置的删除图标时,出现错误:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'id')

这就是代码,如果有帮助的话。 AddLink.js

import { useState, useEffect } from "react";
import classes from "./addlink.module.css";

import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";

import Todo from "../Todo/Todo";

import { v4 as uuidv4 } from "uuid";

initFirebase();
const db = firebase.firestore();

function AddLink(props) {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState("");

  useEffect(() => {
    db.collection("links")
      .orderBy("timestamp", "desc")
      .onSnapshot((snapshot) => {
        // this gives back an array
        setTodos(
          snapshot.docs.map((doc) => ({
            id: doc.id,
            todo: doc.data().todo,
          }))
        );
      });
  }, []);

  const addTodo = (event) => {
    event.preventDefault();

    console.log("clicked");

    db.collection("links").add({
      id: uuidv4(),
      todo: input,
      timestamp: firebase.firestore.FieldValue.serverTimestamp(),
    });
    setInput("");
  };

  return (
    <div className={classes.addlink}>
      <form>
        <div className={classes.adminlink}>
          <input
            type="text"
            value={input}
            onChange={(event) => setInput(event.target.value)}
          />
          <button
            className={classes.adminbutton}
            type="submit"
            onClick={addTodo}
          >
            Add new link
          </button>
        </div>
      </form>
      {todos.map((todo, id) => (
        <Todo value={todo} key={id} />
      ))}
      {/* {modalIsOpen && (
          <Modal onCancel={closeModalHandler} onConfirm={closeModalHandler} />
        )}
        {modalIsOpen && <Backdrop onCancel={closeModalHandler} />} */}
    </div>
  );
}

export default AddLink;

和Todo.js

import React from "react";
import { AiOutlinePicture } from "react-icons/ai";
import { AiOutlineStar } from "react-icons/ai";
import { GoGraph } from "react-icons/go";
import DeleteForeverIcon from "@material-ui/icons/DeleteForever";

import classes from "./todo.module.css";

import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";

initFirebase();
const db = firebase.firestore();

function Todo(props) {
  const deleteHandler = () => {
    db.collection("todos").doc(props.todo.id).delete();
  };

  return (
    <li className={classes.adminsection}>
      <div className={classes.linkCards}>
        <h3>{props.text}</h3>
        <p>This is a new link</p>
        <div>
          <AiOutlinePicture />
          <AiOutlineStar />
          <GoGraph />
          <DeleteForeverIcon onClick={deleteHandler} />
        </div>
      </div>
    </li>
  );
}

export default Todo;

如有任何帮助,我们将不胜感激。

 const deleteHandler = () => {
    db.collection("todos").doc(props.todo.id).delete();
  };

您应该将 props.todo.id 替换为 props.value.id

 const deleteHandler = () => {
    db.collection("todos").doc(props.value.id).delete();
  };

或者您可以更改:

<Todo value={todo} key={id} />

<Todo todo={todo} key={id} />

您用来访问 props.value 的密钥应该与 jsx 模板中声明的密钥相同。使用 proptypes 可以帮助您避免这些错误。

从数据库中删除后,您应该更新状态,UI 为

Todos.filter(d=>d.id !== id of deleted list item)