MERN - удалить элемент / строку в компоненте React Data Table - PullRequest
0 голосов
/ 15 марта 2020

У меня есть приложение стека MERN, которое было изменено из великолепного учебника , которое я завершил. В исходном приложении транзакции отображались в списке, заполненном вызовом API Mon go Atlas DB. Я преобразовал список в компонент реагирующих данных таблицы и теперь пытаюсь выяснить, как удалить строку / транзакцию таблицы. Исходное приложение имело это как часть компонента транзакции с кнопкой onClick. Когда я пытаюсь использовать функцию deleteTransaction, я получаю сообщение «TypeError: Невозможно прочитать свойство« _id »из undefined». Я вижу, что таблица данных визуализируется через объект {транзакции}, но не может понять, почему она не распознает _id.

Другая информация: состояние управляется через React Context API, с маршрутизатором. 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'
    });
  }
}

1 Ответ

1 голос
/ 15 марта 2020

Согласно документам https://www.npmjs.com/package/react-data-table-component#custom -клетки , каждому 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>
    )
  }
]

Каждая строка в основном представляет одну транзакцию.

...