Я получаю предупреждение об уникальном ключе, когда у меня есть уникальный ключ - PullRequest
0 голосов
/ 22 марта 2019

Я новичок в React, но я знаю основную концепцию уникального ключа.Тем не менее, я получаю предупреждение.

Ниже у меня есть компонент предмета:

class Item extends Component {
    state = {}

    render() { 
        return ( 
            <React.Fragment>
                {this.props.item.todo}
            </React.Fragment>
        );
    }
}

А ниже компонент моих предметов и где у меня есть уникальные ключи:

render() { 
    const { items } = this.props;
    return ( 
        items.map(item=>
            <React.Fragment>
                <Item key={item.todo} item={item} />
            </React.Fragment>
        )    
    );
}

При всем этом я получаю предупреждение!

Ответы [ 4 ]

2 голосов
/ 22 марта 2019

Вам нужно оставить реквизиты key на верхнем элементе, как подсказал @Tholle в ответе. Но здесь я хочу предложить не использовать <React.Fragment>:

items.map(item=>
   <Item key={item.todo} item={item} />
)

Fragment используется всякий раз, когда вы не хотите оборачивать элементы оболочкой, например <div />, <p /> и т. Д. Поскольку у вас есть компонент <Item />, использование Fragment не нужно.

Вот пример, если вы можете использовать Fragment:

items.map(item=>
   <React.Fragment key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </React.Fragment>
)

Но извините, если вы используете псевдоним Fragment: <></> не поддерживает key реквизиты. Это должно быть явно установлено без реквизита вообще. Вам нужно будет обернуть их элементом, если вам нужно использовать key:

items.map(item=>
   <div key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </div>
)

Это будет недействительно:

items.map(item=>
   <key={item.todo}>
     <Item item={item} />
     <p>Another Component...</p>
   </>
)
2 голосов
/ 22 марта 2019

Вам нужно поставить опору key на верхний элемент, т.е. React.Fragment вместо Item.

items.map(item=>
  <React.Fragment key={item.todo}>
    <Item item={item} />
  </React.Fragment>
)    
1 голос
/ 22 марта 2019

Как уже говорили другие, вам нужно установить key на верхнем элементе, в вашем случае это Fragment.Но я бы изменил значение ключа.Я не знаю, какие данные у вас в item.todo, но просто установить ключ на значение item.todo может быть проблематично.Я объясню.

Ключ должен быть уникальным только среди своих братьев и сестер В документе activ.org по спискам и ключам это прекрасно суммируется, поэтому я не буду объяснять по-другому.Это сказано ниже.

Ключи, используемые в массивах, должны быть уникальными среди их братьев и сестер.Однако они не должны быть глобально уникальными.Мы можем использовать одни и те же ключи, когда создаем два разных массива:

Ключ должен быть стабильным Это означает, что между рендерами ключ не должен меняться, поэтому не используйте Math.random() который некоторые люди считают целесообразным использовать.

Почему вышеупомянутое важно? По вашим данным, если два items.todo имеют одинаковое значение, тогда оносломал бы вышеупомянутое.Ваш ключ не будет уникальным.Что может привести к проблемам с производительностью из-за ненужных повторных рендеров.

Я бы рекомендовал использовать ключ со значением items.todo и index карты.Таким образом, если у вас одинаковое значение для items.todo, добавление индекса сделает ключ уникальным.Имея это в виду, я бы написал ваш фрагмент.

render() { 
  const { items } = this.props;

  return ( 
    items.map((item, index) => (
      <React.Fragment key={item.todo + index}>
        <Item item={item} />
      </React.Fragment>
    ))
  );
}

Вот ссылка на документацию activ.org в списке и ключи , а также ссылка на документацию activ.org относительно фрагменты .Оба предоставляют примеры и полезную информацию.Они хорошо читаются, и я очень рекомендую.

Также я заметил, что вы используете React.Fragment, но затем вы объявляете свой класс просто с помощью Component.Вы могли бы сделать то, что я предполагаю, что вы сделали для Component и уничтожить Fragement.Примерно так:

import React, { Component, Fragment } from 'react';

Так что ваш фрагмент немного более чистый, как показано ниже:

items.map((item, index) => (
  <Fragment key={item.todo + index}>
    <Item item={item} />
  <Fragment>
))
1 голос
/ 22 марта 2019

дать ключ к React.Fragment

render() { 
  const { items } = this.props;

  return ( 
    items.map(item =>
      <React.Fragment key={item.todo}>
        <Item item={item} />
      </React.Fragment>
    )
  );
}
...