在 React 应用程序中添加项目时,项目列表未更新
Posted
技术标签:
【中文标题】在 React 应用程序中添加项目时,项目列表未更新【英文标题】:Item list is not updated when item is added in React app 【发布时间】:2021-09-10 00:19:27 【问题描述】:我使用 React、MongoDB 和 axios 创建了一个项目列表。
但是,有时新添加的项目只有在手动重新加载浏览器时才会出现在屏幕上(我假设必须重新渲染列表组件,但我不知道该怎么做)。
ExpenseAmountInputContainer.tsx(项目已添加到此组件中)
import React, useState from 'react';
import InputItem from './InputItem';
import AddButton from './AddButton';
import ErrorMessage from './ErrorMessage';
import ExpenseAndAmountObject from '../ExpenseAndAmountObject';
import axios from 'axios';
interface Props
expenseAndAmountList: Array<ExpenseAndAmountObject>;
setExpenseAndAmountList: (value: Array<ExpenseAndAmountObject>) => void;
setTotalExpensesAmount: (value: any) => void;
totalExpenses: number;
const ExpenseAmountInputContainer: React.FC<Props> = (
expenseAndAmountList,
setExpenseAndAmountList,
setTotalExpensesAmount,
totalExpenses,
: Props
) =>
const [Expense, setExpense] = useState<string>('');
const [Amount, setAmount] = useState<string>('');
const [ifNotValidInputs, setIfNotValidInputs] = useState<boolean>(false);
const AddItemToList = () =>
if (Expense !== '' && Amount !== '' && Number(Amount) > 0)
axios.post('http://localhost:4000/app/expenseslist',
expenseTitle: Expense,
expenseAmount: Amount
);
const newTotalExpense = totalExpenses + Number(Amount);
setTotalExpensesAmount(newTotalExpense);
axios.delete('http://localhost:4000/app/totalexpensesamount')
.catch(function (error)
console.log(error);
);
axios.post('http://localhost:4000/app/totalexpensesamount',
totalExpensesAmount: newTotalExpense
);
setExpense("");
setAmount("");
setIfNotValidInputs(false);
else
setIfNotValidInputs(true);
const expensesListResp = async () =>
await axios.get('http://localhost:4000/app/expenseslist')
.then(
response => setExpenseAndAmountList(response.data && response.data.length > 0 ? response.data : []));
expensesListResp();
return (
<div>
<InputItem
onChange=setExpense
onBlur=setExpense
title="Expense"
type="text"
placeholder="Item title"
value=Expense
/>
<InputItem
onChange=setAmount
onBlur=setAmount
title="Amount"
type="number"
placeholder="Expense cost"
value=Amount
/>
<AddButton
onClick=AddItemToList
content="Add expense"
/>
ifNotValidInputs === true ? <ErrorMessage className="error-message"/> : null
</div>
);
;
export default ExpenseAmountInputContainer;
DynamicList.tsx(项目列在此组件中)
import React from "react";
import List from "@material-ui/core";
import ExpensesListItem from './ExpensesListItem';
import ExpenseAndAmountObject from '../ExpenseAndAmountObject';
interface ListItemsArray
expenseAndAmountList: Array<ExpenseAndAmountObject>;
currencySymbol: string;
setExpenseAndAmountList: (value: Array<ExpenseAndAmountObject>) => void;
const DynamicList: React.FC<ListItemsArray> = (
expenseAndAmountList,
currencySymbol,
setExpenseAndAmountList
: ListItemsArray) =>
return (
<>
<List>
expenseAndAmountList.map(item => (
<ExpensesListItem
key=item._id
id=item._id
expenseTitle=item.expenseTitle
expenseAmount=item.expenseAmount
currencySymbol=currencySymbol
item=item
expenseAndAmountList=expenseAndAmountList
setExpenseAndAmountList=setExpenseAndAmountList
/>
))
</List>
</>
);
export default DynamicList;
ExpensesListItem.tsx
import React from "react";
import IconButton, ListItem, ListItemSecondaryAction, ListItemText from "@material-ui/core";
import DeleteIcon from '@material-ui/icons/Delete';
import ExpenseAndAmountObject from '../ExpenseAndAmountObject';
import axios from 'axios';
interface Props
expenseTitle: string;
id: string;
expenseAmount: string;
currencySymbol: string;
item: ExpenseAndAmountObject;
expenseAndAmountList: Array<ExpenseAndAmountObject>;
setExpenseAndAmountList: (value: Array<ExpenseAndAmountObject>) => void;
const ExpensesListItem: React.FC<Props> = (
expenseTitle,
id,
expenseAmount,
currencySymbol,
item,
expenseAndAmountList,
setExpenseAndAmountList
: Props) =>
const DeleteListItem = () =>
setExpenseAndAmountList(expenseAndAmountList.filter(el => el._id !== item._id));
axios.delete('http://localhost:4000/app/expenseslist')
.catch(function (error)
console.log(error);
);
return (
<>
<ListItem className="list-item">
<ListItemText primary=expenseTitle secondary=expenseAmount + currencySymbol />
<ListItemSecondaryAction>
<IconButton onClick=DeleteListItem edge="end">
<DeleteIcon className="delete-btn" />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</>
);
export default ExpensesListItem;
ExpenseAndAmountObject.tsx
export interface ExpenseAndAmountObject
_id: string,
expenseTitle: string,
expenseAmount: string,
如何重新渲染列表组件?谢谢!
【问题讨论】:
【参考方案1】:我认为问题在于异步请求。一开始我不明白你为什么要删除totalexpensesamount
。但是您应该像最后那样使用异步等待按顺序执行请求。
等到删除操作完成,然后进行post请求,完成后,获取新的和更新的对象
您应该在浏览器开发者工具的网络选项卡上检查您的请求和响应。您可以轻松了解问题的根源。 可能您在数据库更新之前调用了一个 get 请求
【讨论】:
对expenseslist
使用异步等待对我有用,谢谢!关于totalexpensesamount
的删除,我将其删除,因为我希望在 MongoDB 中只有一个 totalexpensesamount
值(而不是它们的列表)。也许有更好的方法来实现它,这是我第一个使用数据库的项目
也许你可以采取不同的方法。总费用可以很快改变。我认为将这些数据放在 db 上是一个坏主意,因为它依赖于另一个数据。如果你有后端,你可以在后端计算这个。只需将您的主要对象存储在数据库中。如果调用了 getTotalExpenses 服务,则获取所需的所有费用并计算 BE 端的总费用,然后返回响应以上是关于在 React 应用程序中添加项目时,项目列表未更新的主要内容,如果未能解决你的问题,请参考以下文章
项目输出类型未更改为控制台应用程序,控制台窗口未在 WinForms 中显示
在 React Native 中动态添加项目到 FlatList