微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

“警告:在向列表中添加新元素时,列表中的每个子项都应具有唯一的“键”属性

如何解决“警告:在向列表中添加新元素时,列表中的每个子项都应具有唯一的“键”属性

我正在使用 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,}

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;

如何解决问题?

解决方法

渲染列表时需要传递属性 key

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={} // <-----  SOME UNIQUE ID HERE!!!!!!!!

                    expenseTitle={item.expenseTitle} 
                    expenseAmount={item.expenseAmount}
                    currencySymbol={currencySymbol}
                    item={item}
                    items={expenseAndAmountList}
                    setExpenseAndAmountList={setExpenseAndAmountList}
                  />
                ))} 
            </List>
        </>
      );
  }
  
export default DynamicList;

请参阅解释此行为的文档https://reactjs.org/docs/lists-and-keys.html#keys

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?