2015-04-22 10 views
13

Problem jest następujący:Podając unikalne klucze do komponentów, czy można używać Math.random() do generowania tych kluczy?

Mam dane w formie listy kilku tysięcy elementów. Niektóre z nich są duplikatami, a w takim przypadku może istnieć również szansa posiadania duplikatów kluczy. Ponieważ nie mam prawdziwego "identyfikatora" ani niczego, co dałoby mi możliwość nadania wszystkim elementom ich identyfikatora unikatowych kluczy, czy można zamiast tego używać Math.random()?

Z tego co rozumiem, klucze są używane głównie do reagowania na różnicowanie komponentów. Myślę, że tak naprawdę nie mam nic wspólnego z kluczami w moim kodzie, to powinno pójść dobrze? Aby upewnić się, że nie będzie duplikatu, równie dobrze mogę podzielić dwie randmy matematyczne ze sobą, aby uzyskać prawie na pewno unikalny klucz.

Czy to dobra praktyka? Czy mogę tego używać bez martwienia się o nic?

+0

Ty wystarczy podać klucze, jeśli generujesz tablicę elementów. W takim przypadku równie dobrze można użyć licznika iteracyjnego. –

+0

Po prostu zwiększ liczbę, tak jak zasugerował @FelixKling. To zero ryzyka i proste. – WiredPrairie

+1

@FelixKling Jest to zła rada. Nigdy nie używaj indeksów pętli jako kluczy. Klucz musi być unikalny i spójny. – ffxsam

Odpowiedz

13

Myślę, że twój komponent odmontuje i ponownie zamontuje nowy za każdym razem, gdy zmieni się klucz, więc ze względu na wydajność użycie Math.random() będzie co najmniej suboptymalne.

Jeśli zmienisz kolejność komponentów, użycie indeksu jako klucza nie będzie zbyt pomocne, ponieważ React nie będzie w stanie po prostu przesuwać istniejących węzłów DOM i będzie musiał je ponownie renderować, który znów będzie miał podoptymalną wydajność, ale w tym przypadku tylko przy ponownym zamawianiu listy, więc w twoim przypadku wolałbym używać indeksu zamiast Math.random, pod warunkiem, że nie planujesz zmienić kolejności swojej listy w tak czy inaczej.

Jeśli zamierzasz zmienić kolejność na liście, wygenerowałbym unikalne identyfikatory dla twoich podmiotów, jeśli nie ma żadnych wcześniej istniejących niepowtarzalnych identyfikatorów, których możesz użyć.

Szybki sposób dodawania identyfikatorów to po prostu zmapowanie kolekcji i przypisanie indeksu do każdego elementu po otrzymaniu (lub utworzeniu) kolekcji, np.

const myItemsWithIds = myItems.map((item, index) => { ...item, myId: index }); 

W ten sposób każdy przedmiot otrzymuje unikalny, statyczny identyfikator.

+0

Dzięki. Nie wiedziałem nawet, czy decyzja o tym, czy komponent jest ponownie dostępny, czy nie, opiera się na jego kluczu. – Sossenbinder

+0

Zgodnie z reakcją programu eslint używanie indeksu nie jest niezawodne: "Używanie indeksu tablicowego jest złym pomysłem, ponieważ nie identyfikuje on jednoznacznie swoich elementów. W przypadkach, gdy tablica jest posortowana lub element jest dodawany na początku array, indeks zostanie zmieniony, nawet jeśli element reprezentujący ten indeks może być taki sam, co spowoduje niepotrzebne renderowanie. " Zobacz [brak tablicy-indeksu-klucza] (https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md) – fraxture

4

Od react documentation:

Jeśli nie zapewniają stabilne klawiszy (przy użyciu Math.random() na przykład), wszystkie podrzędne drzewa będą ponownie wydanego za każdym razem. Dając użytkownikom możliwość wyboru klucza, mają możliwość strzelania sobie w stopę.

2

Klucze powinny być stabilne, przewidywalne i niepowtarzalne. Niestabilne klucze (takie jak te produkowane przez Math.random()) spowodują niepotrzebne odtworzenie wielu instancji komponentów i węzłów DOM, co może spowodować degradację wydajności i utratę stanu komponentów potomnych.

https://facebook.github.io/react/docs/reconciliation.html

4

Wystarczy wdrożyć następujący kod w swoim reagować składnik ...

constructor(props) { 
    super(props); 

    this.keyCount = 0; 
    this.getKey = this.getKey.bind(this); 
} 

getKey(){ 
    return this.keyCount++; 
} 

... i nazwać this.getKey() każdym razem trzeba nowy klucz jak:

key={this.getKey()} 
Powiązane problemy