我正在使用 React、Express (axios) 和 MongoDB 开发项目列表。
从 MongoDB 检索列表数组的项目,显示在组件中,用户可以添加新项目(并将它们保存在 MongoDB 中)。
问题是Warning: Each child in a list should have a unique "key" prop"
因为使用属性将新元素添加到列表中id: Math.random()
(尽管这些 id 没有提交到数据库)
App.tsx(这里的项目列表是使用 MongoDB 生成的 id 获取的)
export default function App() {
const [ExpenseAndAmountList, setExpenseAndAmountList] = useState<
Array<{
id: number,
expenseTitle: string,
expenseAmount: string,
}>
>([]);
useEffect(() => {
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 className="App">
<ExpenseAmountInputContainer
expenseAndAmountList={ExpenseAndAmountList}
setExpenseAndAmountList={setExpenseAndAmountList}
setTotalExpensesAmount={setTotalExpensesAmount}
totalExpenses={TotalExpensesAmount}
/>
<DynamicList
expenseAndAmountList={ExpenseAndAmountList}
currencySymbol={Currency}
setExpenseAndAmountList={setExpenseAndAmountList}
/>
</div>
);
}
ExpenseAmountInputContainer.tsx ( HERE 项目发布到 MongoDB 列表,没有任何 id )
interface Props {
expenseAndAmountList: Array<ExpenseAndAmountObject>;
setExpenseAndAmountList: (value: Array<ExpenseAndAmountObject>) => void;
}
const ExpenseAmountInputContainer: React.FC<Props> = (
{
expenseAndAmountList,
setExpenseAndAmountList,
}: Props
) => {
const [Expense, setExpense] = useState<string>('');
const [Amount, setAmount] = useState<string>('');
const AddItemToList = () => {
if (Expense !== '' && Amount !== '' && Number(Amount) > 0) {
axios.post('http://localhost:4000/app/expenseslist',
{
expenseTitle: Expense,
expenseAmount: Amount
});
setExpense("");
setAmount("");
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"
/>
</div>
);
};
export default ExpenseAmountInputContainer;
ExpenseAndAmountObject.tsx(在 ExpenseAmountInputContainer.tsx 中使用的接口)
export interface ExpenseAndAmountObject {
id: number,
expenseTitle: string,
expenseAmount: string,
}
动态列表.tsx
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
expenseTitle={item.expenseTitle}
expenseAmount={item.expenseAmount}
currencySymbol={currencySymbol}
item={item}
items={expenseAndAmountList}
setExpenseAndAmountList={setExpenseAndAmountList}
/>
))}
</List>
</>
);
}
export default DynamicList;
问题如何解决?