React - 为数组映射添加唯一键

IT技术 javascript reactjs ecmascript-6
2021-05-21 01:46:27

我想为该函数提供的返回元素添加一个唯一键。

function RowList() {
  const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
  return (
    <>
      {rows.map(row => (
        <tr key={?}>{row}</tr>
      ))}
    </>
  );
}

我努力了:

function Rows() {
  const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
  return (
    <>
      {rows.map(row => (
        <tr key={row}>{row}</tr>
      ))}
    </>
  );
}

但是[object Object]作为key返回。

我也将无法做类似的事情

let x = 0
function Rows() {
  const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
  return (
    <>
      {rows.map(row => (
        <tr key={x = x + 1}>{row}</tr>
      ))}
    </>
  );
}

因为我稍后需要能够删除并添加回数组。

1个回答

如您所知,您不能只这样做:

// DON'T DO THIS
{rows.map((row, index) => (
  <tr key={index}>{row}</tr>
))}

正如文档所说,这是“最后的手段”,实际上只对静态列表有用。你说过你的列表不会是静态的。

拥有像这样的已经创建的元素数组而不是元素数据数组是相当不寻常的。如果你能避免它,我会,并给数据条目持久的 ID 值,你可以用作键,例如(name显然是实际数据的替代品):

class RowInfo {
  static id = 0;
  constructor(name) {
    this.name = name;
    this.id = RowInfo.id++;
  }
}

function RowList() {
  const rows = [new RowInfo("one"), new RowInfo("two"), new RowInfo("three"), new RowInfo("four")];
  return (
    <>
      {rows.map(({id, name}) => (
        <tr key={id}><Row name={name}/></tr>
      ))}
    </>
  );
}

这假设它们都应该是相同类型的组件,当然,这可能不是真的。

如果您不能这样做并且必须预先创建实际元素,我可能会创建包装器对象:

class RowInfo {
   static id = 0;
   constructor(element) {
     this.element = element;
     this.id = RowInfo.id++;
   }
}
function RowList() {
  const rows = [new RowInfo(<Row0 />), new RowInfo(<Row1 />), new RowInfo(<Row2 />), new RowInfo(<Row3 />)];
  return (
    <>
      {rows.map(({id, element}) => (
        <tr key={id}>{element}</tr>
      ))}
    </>
  );
}

或者,如果它们没有您需要指定的任何props,您可以让 React 跟踪它们,因为这是其工作的一部分:

class RowInfo {
   static id = 0;
   constructor(Comp) {
     this.Comp = Comp;
     this.id = RowInfo.id++;
   }
}
function RowList() {
  const rows = [new RowInfo(Row0), new RowInfo(Row1), new RowInfo(Row2), new RowInfo(Row3)];
  return (
    <>
      {rows.map(({id, Comp}) => (
        <tr key={id}><Comp/></tr>
      ))}
    </>
  );
}

这是一个活生生的例子: