Я получал видео из 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.
Что срочно использовать UUID? На самом деле у вас есть video.id.videoId
за это
@cmgchess Я знаю, что это был бы лучший сценарий, но я хочу выяснить, есть ли способ сгенерировать постоянный (или стабильный) ключ с uuid.
@DennisVash в списке, из которого я извлекаю, есть дубликаты. video.id.videoId тоже не уникален.
Вы генерируете новый uuid для каждого элемента каждый раз, когда запускается карта. Если вы хотите, чтобы он был стабильным при рендеринге, вам нужно назначить идентификаторы один раз, вне функции карты.
Какой смысл в идентификаторе, если он не уникален? Таким образом, даже если вы дедуплицировали свой набор данных, все равно остались бы объекты с повторяющимися идентификаторами?
Я не думаю, что есть какие-то проблемы в том, как вы это реализовали. Почему вы хотите иметь фиксированные идентификаторы? Это будет работать нормально. Если вам все еще не все равно, вы можете определить список исправлений UUID и предоставить их в качестве ключей. Кроме того, нет необходимости прикреплять uuid к видеообъекту. Вы можете напрямую предоставить ключ.
определите переменную, которая содержит значение 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, чтобы увидеть, меняются ли ключи всякий раз, когда фрагмент видео добавляется к предыдущим видео, и все ключи меняются.
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>
}
Спасибо, но это не помешает реакции генерировать новые идентификаторы для каждого видео для каждого рендера.
Да, принятый ответ - это то, что нужно, не думал об этом, но обычно вы сохраняете его в состоянии либо локально, либо в контексте.
Правильным способом было бы получить идентификатор непосредственно из того места, где вы получаете видео.
Следующим будет генерировать их в тот момент, когда вы получаете их из удаленного местоположения (предполагая, что вы получаете их из 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
....
}
если есть что-то уникальное для каждого видео использовать его? или если есть комбинация полей, которые делают его уникальным?