【问题标题】:How to delete data from database by using React js and REST API如何使用 React js 和 REST API 从数据库中删除数据
【发布时间】:2020-03-26 03:59:18
【问题描述】:

我正在学习 REST API。我正在将 react 应用程序用于 Node js 和 express 服务器的前端和后端。对于 API,我使用的是 REST API。我正在使用 MongoDB 作为数据库。我成功地将所有数据显示到浏览器。我可以搜索数据。现在我想删除数据。我不知道如何从 REST API 端点删除数据。如果有人帮助我,我会非常高兴。我使用 Postman 测试了我的后端。一切都按预期正常工作。

这是我的后端删除终点

app.delete("/students/:id", async (req, res, next) => {
  const id = req.params.id;

  try {
    student
      .remove({ _id: id })
      .exec()
      .then(data => {
        res.json(data);
      });
  } catch (error) {
    console.log(error);
  }
});

我将我的 API END 点导出到 React js

 export async function deleteStudent(id) {
  const response = await fetch(`/students/${id}`, {
    method: "DELETE"
  });
  return response.json();
}

这是我要删除数据的主要组件

 import React, { useState, useEffect } from "react";
import { logEntry } from "../Api/Api";
import { deleteStudent } from "../Api/Api";

function Datatable() {
  const [total, settotal] = useState([]);
  const [searchItem, setsearchItem] = useState({
    item: ""
  });
  const [data, setdata] = useState([]);

  const handleChange = e => {
    setsearchItem({ item: e.target.value });
  };

  const getEntries = async () => {
    const logEntries = await logEntry();

    console.log(logEntries);
    settotal(logEntries.count);
    setdata(logEntries.students);
  };

  const nameFilter = data.filter(list => {
    return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
  });

  const deleteData = async id => {
    await deleteStudent(id);
  };

  useEffect(() => {
    getEntries();
  }, []);
  return (
    <div>
      <div style={{ paddingLeft: "800px" }}>
        <input
          placeholder="Search student"
          onChange={handleChange}
          style={{ width: "200px", height: "30px" }}
        />
      </div>
      <p>Total student: {total} </p>
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>City</th>
            <th>Address</th>
            <th>Phone</th>
            <th>Email</th>
          </tr>
        </thead>

        <tbody>
          {nameFilter === "" ? (
            <p>Student not found</p>
          ) : (
            nameFilter.map(list => {
              return (
                <tr>
                  <td>{list.name}</td>
                  <td>{list.city}</td>
                  <td>{list.address}</td>
                  <td>{list.phone}</td>
                  <td>{list.email}</td>
                  <td>
                    <a
                      className="waves-effect red btn-small"
                      onClick={() => deleteData(list.id)}
                    >
                      Delete
                    </a>
                  </td>
                </tr>
              );
            })
          )}
        </tbody>
      </table>
    </div>
  );
}

export default Datatable;

我不知道,我在做什么?

【问题讨论】:

    标签: reactjs rest


    【解决方案1】:

    这看起来是一个很好的开始!我的理解是,您需要通过 &lt;DataTable&gt; 组件中的“删除”按钮以某种方式将要删除的 studentid 传递到 deleteStudent() 中的 URL。

    所以,首先,让我们重构您的 deleteStudent() 函数:

    export async function deleteStudent(id) {
      const response = await fetch(`/students/${id}`, {
        method: "DELETE",
      });
      return response.json();
    }
    

    您不需要使用 DELETE 请求发送任何数据,您只需根据 id 访问正确的 URL,我们可以将其传递给方法并动态包含在 fetch() 调用中。

    现在,您需要找到某种方法将 id 传递给 deleteStudent() 函数。据我所知,您正在这里提取学生数据(我已经解释过):

    const getEntries = async () => {
    
        // students are pulled in, I'm assuming they have an 'id' property that corresponds to the 'id' that MongoDB has them stored under
        const logEntries = await logEntry();
    
        // and now data references the students
        setdata(logEntries.students);
    
      };
    

    看起来你在这里过滤学生:

    const nameFilter = data.filter(list => {
      return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
    });
    

    然后通过调用 .map() 来渲染过滤后的学生。这是您可以在onClick 处理程序中传递id 的地方,假设您在这些list 元素上有一个id 字段。如果您不这样做,那么您需要找到一种方法将 id 添加到此数据中:

    nameFilter.map(list => {
      return (
        <tr>
          <td>{list.name}</td>
          <td>{list.city}</td>
          <td>{list.address}</td>
          <td>{list.phone}</td>
          <td>{list.email}</td>
          <td>
            <a
              className="waves-effect red btn-small"
              onClick={() => deleteData(list.id)} // this is where the id should get passed on to the handler, and then dynamically included in the DELETE /students/:id url
            >
              Delete
            </a>
          </td>
        </tr>
      );
    })
    

    然后,在您的deleteData() 函数中,您将收到id 作为参数,您可以调用您的deleteStudent(id) 函数向后端发出请求:

    const deleteData = async id => {
      await deleteStudent(id);
    };
    

    还有一些其他的事情需要处理,但您的总体思路是正确的!我将在下面给出一些进一步改进的提示。

    这些需要分开,还是可以合并?

    import { logEntry } from "../Api/Api";
    import { deleteStudent } from "../Api/Api";
    

    也许清理 DELETE 路由处理程序:

    app.delete("/students/:id", async (req, res, next) => {
    
      const id = req.params.id;
    
      try {
        // generally, Mongoose Model's are represented with TitleCase
        Student
          .remove({ _id: id })
          .exec() // is this needed? https://mongoosejs.com/docs/api/model.html#model_Model-remove
          .then(data => {
            res.json(data);
          });
      } catch (error) {
        console.log(error);
      }
    });
    

    这个数据表中似乎有一些额外的状态/钩子:

    function Datatable() {
    
      // ... bunch of code
    
      // do you need state for this?
      const [removeStudent, setremoveStudent] = useState([]);
    
      // ... more code
    
      const getEntries = async () => {
    
        // ... 
    
        setremoveStudent(deleteData); // not sure this is needed...
      };
    

    【讨论】:

    • 用于拉取数据的日志条目。它有另一个端点。 export async function logEntry() { const response = await fetch("/students"); return response.json(); }’. for delete used delete entry export async function deleteStudent(id) { const response = await fetch(/students/${id}, { method: "DELETE" });返回响应.json(); }'
    • 用于搜索数据的名称过滤器。
    • 我按照您的建议进行了修改,但删除按钮不起作用:(
    • 是的,我理解这两件事。您导入 logEntry 的方式,它来自与 deleteStudent 相同的文件,因此您可以执行从“react”库导入多个钩子时使用的相同类型的导入。 nameFilter 搜索数据,但也负责渲染它。
    • 以什么方式不起作用? 'deleteData' 处理程序是否正在运行,还是来自 deleteStudent() 的 fetch() 请求有问题?
    猜你喜欢
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 2020-12-03
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多