Реагировать - Добавить уникальный ключ на карту массива - PullRequest
2 голосов
/ 10 июля 2019

Я хотел бы добавить уникальный ключ к возвращаемым элементам, которые предоставляет эта функция.

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] возвращается как ключ.

Я также не смогу сделать что-то вроде

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

Так как позже мне понадобится удалить и добавить обратно в массив.

1 Ответ

1 голос
/ 10 июля 2019

Как вы знаете, вы не можете просто сделать это:

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

Как сказано в документации , это "последнее средство" и действительно полезно только для статических списков. Вы сказали, что ваш список не будет статичным.

Довольно необычно иметь массив уже созданных подобных элементов, а не массив данных для элементов. Если бы вы могли избежать этого, я бы дал и записи данных с постоянными значениями идентификаторов, которые вы можете использовать в качестве ключей, например, (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>
      ))}
    </>
  );
}

Или, если у них нет реквизита, который вам нужно указать, вы можете позволить 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>
      ))}
    </>
  );
}

Вот живой пример этого:

const Row0 = () => <div>Row 0</div>;
const Row1 = () => <div>Row 1</div>;
const Row2 = () => <div>Row 2</div>;
const Row3 = () => <div>Row 3</div>;

const {Fragment} = React;

class RowInfo {
   static id = 0;
   constructor(Comp) {
     this.Comp = Comp;
     this.id = RowInfo.id++;
   }
}
// Have to use <Fragment></Fragment> in the below instead of <></> because
// Stack Snippet's version of Babel is out of date and
// doesn't understand <></>.
function RowList() {
  const rows = [new RowInfo(Row0), new RowInfo(Row1), new RowInfo(Row2), new RowInfo(Row3)];
  return (
    <Fragment>
      {rows.map(({id, Comp}) => (
        <tr key={id}><Comp/></tr>
      ))}
    </Fragment>
  );
}

ReactDOM.render(<RowList/>, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...