Правильный способ использовать uuid в качестве ключа в React?

Я получал видео из API, и там были дубликаты. Итак, я применил uuid для генерации ключа для каждого — key={uuid()} — пока не понял, что генерирую новый ключ для каждого рендера.

Ниже приведено мое исправление, но я не совсем уверен, действительно ли оно решает проблему.

export default function VideoList({ videos, observedElement }) {
  const location = useLocation();

  const videoList = videos.map((video, index) => {
    video.uuid = uuid();

    return (
      <Link
        to={`/videos/${video.id.videoId}`}
        state={{ backgroundLocation: location }}
        key={video.uuid}
      >
        <VideoListEntry info={video} ref={observedElement} />
      </Link>
    );

  return <div>{videoList}</div>
}

Обновлено: я знаю, что использование идентификатора из базы данных или создание комбинации в заданных данных предпочтительнее. Но я просто хочу знать, есть ли способ сгенерировать стабильный ключ с uuid.

если есть что-то уникальное для каждого видео использовать его? или если есть комбинация полей, которые делают его уникальным?

cmgchess 10.04.2022 08:57

Что срочно использовать UUID? На самом деле у вас есть video.id.videoId за это

Dennis Vash 10.04.2022 08:57

@cmgchess Я знаю, что это был бы лучший сценарий, но я хочу выяснить, есть ли способ сгенерировать постоянный (или стабильный) ключ с uuid.

Ordinary Probably 10.04.2022 08:59

@DennisVash в списке, из которого я извлекаю, есть дубликаты. video.id.videoId тоже не уникален.

Ordinary Probably 10.04.2022 09:00

Вы генерируете новый uuid для каждого элемента каждый раз, когда запускается карта. Если вы хотите, чтобы он был стабильным при рендеринге, вам нужно назначить идентификаторы один раз, вне функции карты.

ray hatfield 10.04.2022 09:09

Какой смысл в идентификаторе, если он не уникален? Таким образом, даже если вы дедуплицировали свой набор данных, все равно остались бы объекты с повторяющимися идентификаторами?

Andy 10.04.2022 09:29

Я не думаю, что есть какие-то проблемы в том, как вы это реализовали. Почему вы хотите иметь фиксированные идентификаторы? Это будет работать нормально. Если вам все еще не все равно, вы можете определить список исправлений UUID и предоставить их в качестве ключей. Кроме того, нет необходимости прикреплять uuid к видеообъекту. Вы можете напрямую предоставить ключ.

ABGR 10.04.2022 09:44
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
7
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

определите переменную, которая содержит значение uuid, подобное этому, и используйте ее, я думаю, это сработает для вас

export default function VideoList({ videos, observedElement }) {
  const location = useLocation();

  const videoList = videos.map((video, index) => {
    let uuid = uuid()
    video.uuid = uuid 

    return (
      <Link
        to={`/videos/${video.id.videoId}`}
        state={{ backgroundLocation: location }}
        key={uuid}
      >
        <VideoListEntry info={video} ref={observedElement} />
      </Link>
    );

  return <div>{videoList}</div>
}

Спасибо, но ваше предложение не работает. Я смотрю React devtool, чтобы увидеть, меняются ли ключи всякий раз, когда фрагмент видео добавляется к предыдущим видео, и все ключи меняются.

Ordinary Probably 10.04.2022 09:21
export default function VideoList({ videos, observedElement }) {
  const location = useLocation();

  videos.forEach(video => video.uuid = uuid()); // loop through the list and generate the id
  
  const videoList = videos.map((video, index) => {
    return (
      <Link
        to={`/videos/${video.id.videoId}`}
        state={{ backgroundLocation: location }}
        key={video.uuid}
      >
        <VideoListEntry info={video} ref={observedElement} />
      </Link>
    );

  return <div>{videoList}</div>
}

Спасибо, но это не помешает реакции генерировать новые идентификаторы для каждого видео для каждого рендера.

Ordinary Probably 10.04.2022 10:06

Да, принятый ответ - это то, что нужно, не думал об этом, но обычно вы сохраняете его в состоянии либо локально, либо в контексте.

Enfield li 10.04.2022 10:09
Ответ принят как подходящий

Правильным способом было бы получить идентификатор непосредственно из того места, где вы получаете видео.

Следующим будет генерировать их в тот момент, когда вы получаете их из удаленного местоположения (предполагая, что вы получаете их из API). Итак, сразу после их получения обогащайте их uuid, а затем сохраняйте в состояние/хранилище.

Третье решение — использовать useEffect внутри вашего компонента, который будет генерировать идентификаторы только при изменении свойства видео.

export default function VideoList({
  videos = [],
  observedElement
}) {
  const location = useLocation();
  const [videosWithId, setVideosWithId] = useState(videos);

  useEffect(() => {
    const withId = videos.map(video => ({
      ...video,
      uuid: uuid()
    }))
    setVideosWithId(withId);
  }, [videos]);

  // use videosWithId from below this point, instead of the videos prop
  ....

}

Другие вопросы по теме