如何在 React Hooks 中向 table 添加行而不重复?

How do I add rows to a table in React Hooks without getting duplicates?

我正在尝试使用 React 挂钩创建数据 table,但我的状态中不断出现重复的行。这是我获取值进行一些操作然后调用我的函数来更新状态的调用:

var tableRowIndex = 0;
const CoinTable = () => {
    const baseURL = 'endpoint/';
    const [tableRows, setRows] = useState([] as any);


    const getCurrentPrice = async (inputs: any) => {
        const response = await axios.get(`${baseURL}${inputs.currency}/USD`)
        let currentPrice = response.data
        inputs.cryptoPrice = currentPrice.rate;
        let coinsRequired = inputs.amount / inputs.cryptoPrice;
        inputs.amtCrypto = coinsRequired.toFixed(8);
        addNewRow(inputs)
    }

这是我尝试更新状态的函数

 const addNewRow = (inputs: any) => {
        tableRowIndex++
        inputs.index = tableRowIndex
        setRows([...tableRows, inputs])
    }

这是我映射行并在我的 JSX 中输出的其余组件。

const rows = tableRows.map((row: any) => {
        return (
            <TableRow
                key={tableRowIndex}
                addNewRow={addNewRow}
                removeRow={removeRowHandler}
                getCurrentPrice={getCurrentPrice}
                row={row}
            />
        )
    })
    
    return (
        <>
            <AddItem
                getCurrentPrice={getCurrentPrice}
            />
            {tableRows.length > 0 &&
                <table>
                    <tbody>
                        <tr>
                            <th>Merchant</th>
                            <th>Item</th>
                            <th>Amount(Crypto)</th>
                            <th>Currency</th>
                            <th>Price/crypto(USD)</th>
                            <th>Amount(USD)</th>
                        </tr>
                        {rows}
                    </tbody>
                </table>

            }
        </>
    )
}

export default CoinTable;

Inputs 是包含要呈现为新行的用户输入的对象。这似乎是我如何使用展开运算符更新状态的问题,但我不确定。

您好像在使用单个 tableRowIndex“全局”值作为每个映射元素的 React 键。您可能打算使用 row indexgenerated inaddNewRowwhen adding an element to thetableRows` 状态。

const addNewRow = (inputs: any) => {
  tableRowIndex++;
  inputs.index = tableRowIndex; // <-- assigned here
  setRows([...tableRows, inputs]);
}

...

const rows = tableRows.map((row: any) => {
  return (
    <TableRow
      key={row.index} // <-- used here
      addNewRow={addNewRow}
      removeRow={removeRowHandler}
      getCurrentPrice={getCurrentPrice}
      row={row}
    />
  )
})

一个更惯用的方法是调用这个增强的 属性 id 所以它 abundantly 清楚它是不是任何数组索引,实际上是分配给每个元素的唯一值。我什至会说您可能想要使用为您生成 GUID 的库。 uuid 很棒。

import { v4 as uuidV4 } from 'uuid';

...

const addNewRow = (inputs: any) => {
  setRows(rowData => [
    ...rowData,
    {
      ...inputs,   // <-- don't mutate inputs object
      id: v4uuid() // <-- assign unique id
    },
  ]);
}

...

const rows = tableRows.map((row: any) => {
  return (
    <TableRow
      key={row.id}
      addNewRow={addNewRow}
      removeRow={removeRowHandler}
      getCurrentPrice={getCurrentPrice}
      row={row}
    />
  )
})