删除模态。反应 Redux。无法读取未定义的属性“_id”
Posted
技术标签:
【中文标题】删除模态。反应 Redux。无法读取未定义的属性“_id”【英文标题】:Delete Modal. React Redux. Cannot read property '_id' of undefined 【发布时间】:2021-10-07 12:01:59 【问题描述】:尝试删除费用跟踪器的交易。当用户点击垃圾桶图标时,应该会出现一个模式。相反,无法读取未定义的属性“_id”。
我猜我需要一个带有 match.params 的 useEffect 钩子?还是我需要在模态框上再次列出交易?
数据
const transactions = [
name: "Rent",
href: "#",
category: "expense",
amount: "-1000",
currency: "USD",
status: "processing",
date: "July 1, 2020",
datetime: "2020-07-11",
,
name: "Google",
href: "#",
category: "income",
amount: 5000,
currency: "USD",
status: "success",
date: "July 18, 2020",
datetime: "2020-07-18",
,
name: "Facebook",
href: "#",
category: "income",
amount: "15000",
currency: "USD",
status: "success",
date: "July 18, 2020",
datetime: "2020-07-18",
,
name: "Payment to Molly Sanders",
href: "#",
category: "expense",
amount: "-2000",
currency: "USD",
status: "success",
date: "July 11, 2020",
datetime: "2020-07-11",
,
];
export default transactions;
app.js
function App()
return (
<Router history=history>
<Route path='/' exact component=DashboardScreen />
<Route path='/transaction/add' exact component=AddTransactionModal />
<Route
path='/transactions/delete/:id'
exact
component=DeleteTransactionModal
/>
</Router>
);
交易清单:
import React, useEffect from "react";
import Link from "react-router-dom";
import useDispatch, useSelector from "react-redux";
const TransactionList = () =>
const dispatch = useDispatch();
const transactionList = useSelector((state) => state.transactionList);
const loading, error, transactions = transactionList;
useEffect(() =>
dispatch(listTransactions());
, [dispatch]);
return (
<div className=''>
<h2 className=''>
Recent activity
</h2>
<div className=''>
<nav
className=''
aria-label='Pagination'>
<div className='f'>
<a
href='#'
className=''>
Previous
</a>
<a
href='#'
className=''>
Next
</a>
</div>
</nav>
</div>
<div className=''>
<table className=''>
<thead>
<tr>
<th className=''>
Transaction
</th>
<th className=''>
Amount
</th>
<th className=''>
Action
</th>
<th className=''>
Date
</th>
</tr>
</thead>
<tbody className=''>
transactions.map((transaction) => (
<tr key=transaction.id className=''>
<td className=''>
<div
className="">
<a
href=transaction.href
className=''>
<CashIcon
className=''
aria-hidden='true'
/>
<p className=''>
transaction.name
</p>
</a>
</div>
</td>
<td className=''>
<span className=''>
numberWithCommas(transaction.amount)" "
</span>
transaction.currency
</td>
<td className=''>
<span className=' '>
<Link to=`/transactions/delete/$transaction.id`>
<TrashIcon
className=''
aria-hidden='true'
/>" "
</Link>
<Link>
<PencilAltIcon
className=''
aria-hidden='true'
/>
</Link>
</span>
</td>
<td className=''>
<time dateTime=transaction.datetime>
transaction.date
</time>
</td>
</tr>
))
</tbody>
</table>
</div>
</div>
);
;
export default TransactionList;
删除交易模式:
import React from "react";
import useRef, useState, useEffect from "react";
import useParams from "react-router-dom";
import connect, useDispatch, useSelector from "react-redux";
import Redirect, Link from "react-router-dom";
import
deleteTransaction,
from "../../actions/transactionActions";
import DashboardScreen from "../../screens/DashboardScreen";
import StandardModal from "./StandardModal";
const DeleteTransactionModal = () =>
const dispatch = useDispatch();
const id = useParams();
const [open, setOpen] = useState(true);
const cancelButtonRef = useRef(null);
if (!open)
return <Redirect to='/' />;
const actions = (
<React.Fragment>
<button
type='button'
onClick=() => dispatch(deleteTransaction(id))
className=''>
Delete
</button>
<Link
to='/'
type='button'
className=''
onClick=() => setOpen(false)
ref=cancelButtonRef>
Cancel
</Link>
</React.Fragment>
);
return (
<div>
<DashboardScreen />
console.log(transaction.id)
<StandardModal
title='Delete Transaction'
content='Are you sure you want to delete this transaction?'
actions=actions
/>
</div>
);
;
export default connect(null, deleteTransaction )(DeleteTransactionModal);
【问题讨论】:
什么是渲染DeleteTransactionModal
并将道具传递给它?该错误似乎暗示 transaction
属性未定义。
所以我认为DeleteTransactionModal
是由Route
渲染的,其路径类似于"/transactions/delete/:id"
?是的,您可以访问路由参数并提取交易 ID。如果DeleteTransactionModal
没有在路由上渲染,而是由另一个组件渲染,则需要传递所有的props。
是的,这正是它的路由方式。我刚刚再次更新了帖子。如果不使用 this
关键字,您将如何提取交易 ID?
不确定this
来自哪里,但this
在函数组件中只是未定义。不过,我确实在下面提供了有关如何访问路由参数的答案。
好的,所以我用你的建议更新了模态,如上所示。但是,我现在在 URL 中获取事务/删除/未定义,而不是 ID 号。
【参考方案1】:
由于DeleteTransactionModal
是由路由直接渲染的,所以从作为props传递的route props访问事务id
。
const DeleteTransactionModal = (
deleteTransaction,
match, // <-- destructure the match prop
) =>
const id = match.params; // <-- access the id param
const actions = (
<React.Fragment>
<button
type='button'
onClick=() => deleteTransaction(id) // <-- pass id to action
className='modal-css'
>
Delete
</button>
<Link
to='/'
type='button'
className='modal-css'
onClick=() => setOpen(false)
ref=cancelButtonRef
>
Cancel
</Link>
</React.Fragment>
);
return (
<div>
<DashboardScreen />
<StandardModal
title='Delete Transaction'
content='Are you sure you want to delete this transaction?'
actions=actions
/>
</div>
);
export default connect(null, deleteTransaction )(
DeleteTransactionModal
);
我建议使用 connect
HOC 转换为 React 挂钩。
import useDispatch from 'react-redux';
import useParams from 'react-router-dom';
const DeleteTransactionModal = () =>
const dispatch = useDispatch();
const id = useParams();
const actions = (
<React.Fragment>
<button
type='button'
onClick=() => dispatch(deleteTransaction(id))
className='modal-css'
>
Delete
</button>
<Link
to='/'
type='button'
className='modal-css'
onClick=() => setOpen(false)
ref=cancelButtonRef
>
Cancel
</Link>
</React.Fragment>
);
return (
<div>
<DashboardScreen />
<StandardModal
title='Delete Transaction'
content='Are you sure you want to delete this transaction?'
actions=actions
/>
</div>
);
路线优化建议
由于您似乎一次只想渲染一条路线,因此将它们渲染到 Switch
组件中,并将路线从最具体的路径重新排序到最不具体的路径。这允许您删除 exact
属性。
<Router history=history>
<Switch>
<Route path='/transactions/delete/:id' component=DeleteTransactionModal />
<Route path='/transaction/add' component=AddTransactionModal />
<Route path='/' component=DashboardScreen />
</Switch>
</Router>
【讨论】:
以上是关于删除模态。反应 Redux。无法读取未定义的属性“_id”的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:无法读取未定义反应redux的属性“历史”[重复]
反应笑话单元测试用例TypeError:无法读取未定义的属性'then'
React Redux TypeError:无法读取未定义的属性“地图”