У меня есть приложение стека 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'
});
}
}