MERN - 删除 React Data Table 组件中的 item/row

MERN - delete item/row in React Data Table Component

我有一个 MERN 堆栈应用程序,它是从我完成的一个很棒的 tutorial 修改而来的。在原始应用程序中,事务在一个列表中呈现,该列表由对 Mongo Atlas DB 的 API 调用填充。我将列表转换为 react-data-table-component,现在我想弄清楚如何删除 table row/transaction。原始应用程序将其作为带有 onClick 按钮的事务组件的一部分。当我尝试使用 deleteTransaction 函数时,我收到 "TypeError: Cannot read property '_id' of undefined"。我可以看到数据 table 通过对象 {transactions} 呈现,但无法弄清楚为什么它不识别 _id。

其他信息:状态通过 React 上下文 API 管理,具有 Router.js 和 Reducer.js。

TransactionTable.js

import React, { useContext, useEffect } from "react";

// Data table imports
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import Card from "@material-ui/core/Card";
import DataTable from "react-data-table-component";

// import transaction component and context provider
import { GlobalContext } from "../context/GlobalState";

// create data table component
export const TransactionTable = () => {
  const { transactions, getTransactions, deleteTransaction } = useContext(
    GlobalContext
  );

  // react-data-table-component Columns for back-end data
  const columns = [
    {
      name: "Transaction",
      selector: "text",
      sortable: true
    },
    {
      name: "Amount",
      selector: "amount",
      sortable: true,

      // conditionally render amount if positive or negative
      conditionalCellStyles: [
        {
          when: row => row.amount > 0,
          style: {
            color: "green"
          }
        },
        {
          when: row => row.amount < 0,
          style: {
            color: "red"
          }
        }
      ]
        },
        {
// where I'm attempting to pass the transactions prop and apply the deleteTransaction function 
// using the delete button that renders in each row
          cell: ({ transactions }) => (
            <IconButton
              aria-label="delete"
              color="secondary"
              onClick={() => deleteTransaction(transactions._id)}
            >  
              <DeleteIcon />
            </IconButton>
          )
        }
      ];

      useEffect(() => {
        getTransactions();
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);

      return (
        <div>
        <Card style={{ height: "100%" }} p={2} mx="auto">
            <DataTable
              title="Transactions"
              columns={columns}
              data={transactions}
              defaultSortField="Transactions"
              //actions={actions}
              pagination={true}
              highlightOnHover={true}
              dense={true}
            />
          </Card>
        </div>
      );
    };

./controllers/transactions.js - 这是 deleteTransaction 函数所在的地方

const Transaction = require('../models/Transaction');

// @desc    Get all transactions
// @route   GET /api/v1/transactions
// @access  Public
exports.getTransactions = async (req, res, next) => {
  try {
    const transactions = await Transaction.find();
    //const result = result.transaction.toString()

    return res.status(200).json({
      success: true,
      count: transactions.length,
      data: transactions
    });
  } catch (err) {
    return res.status(500).json({
      success: false,
      error: 'Server Error'
    });
  }
}

// @desc    Add transaction
// @route   POST /api/v1/transactions
// @access  Public
exports.addTransaction = async (req, res, next) => {
  try {
    const { text, amount } = req.body;

    const transaction = await Transaction.create(req.body);

    return res.status(201).json({
      success: true,
      data: transaction
    }); 
  } catch (err) {
    if(err.name === 'ValidationError') {
      const messages = Object.values(err.errors).map(val => val.message);

      return res.status(400).json({
        success: false,
        error: messages
      });
    } else {
      return res.status(500).json({
        success: false,
        error: 'Server Error'
      });
    }
  }
}

// @desc    Delete transaction
// @route   DELETE /api/v1/transactions/:id
// @access  Public
exports.deleteTransaction = async (req, res, next) => {
  try {
    const transaction = await Transaction.findById(req.params.id);

    if(!transaction) {
      return res.status(404).json({
        success: false,
        error: 'No transaction found'
      });
    }

    await transaction.remove();

    return res.status(200).json({
      success: true,
      data: {}
    });

  } catch (err) {
    return res.status(500).json({
      success: false,
      error: 'Server Error'
    });
  }
}

根据文档 https://www.npmjs.com/package/react-data-table-component#custom-cells,每个 cell 都会被传递一个名为 row 的对象(您可以随意命名)。

这个 row 对象应该有你需要的 _id..

// react-data-table-component Columns for back-end data
const columns = [
  // ... column items,
  {
    cell: row => (
      <IconButton
        aria-label="delete"
        color="secondary"
        onClick={() => deleteTransaction(row._id)}
      >  
        <DeleteIcon />
      </IconButton>
    )
  }
]

每一行基本上代表一个事务。