【发布时间】:2021-06-15 04:57:19
【问题描述】:
我正在使用 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(这里的项目被发布到没有任何 id 的 MongoDB 列表)
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,
}
DynamicList.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;
这个问题怎么解决?
【问题讨论】:
-
您在哪里设置项目 ID 属性?您是否将它们设置在后端?
Math.random确实不是生成唯一 ID 的好用例。 -
我的评论具有误导性,我没有使用
Math.random。 AT ExpenseAmountInputContainer.tsx 项目在没有任何 id 的情况下发布到 MongoDB(因为它们是在 MongoDB 中生成的) -
尽管如此,在将新元素添加到列表时,仍不清楚您在哪里添加任何
id属性。ids 在哪里生成?错误在哪里抛出?看来您正在后端生成它们。如果它们不是唯一的,那么您将遇到此前端问题。可以看看相关的后端代码吗? -
在 DynamicList.tsx 中,您是否为使用
map()创建的组件设置 key prop? -
我没有在任何地方设置 key prop,我只是在
<List>中添加了一个属性key={item.id}。我正在尝试实现该 item.id 将是由 MongoDB 生成的_id(也许这不是正确的方法..?)
标签: reactjs typescript mongodb list ids