Pierwszy, być jasne, dlaczego używasz key
...
Podanie key
dla każdej pozycji na liście jest przydatna, gdy ta lista jest dość dynamiczny - gdy nowe elementy listy są regularnie dodawane i usuwane, zwłaszcza jeśli lista jest długa, a elementy są dodawane/usuwane w górnej części listy.
keys
może przynieść duże zyski wydajności, ponieważ umożliwiają one bardziej wydajne ponowne rysowanie tych zmiennych list. A dokładniej, pozwala Reactowi na uniknięcie przerysowywania przedmiotów, które mają ten sam klucz co poprzednio, a które się nie zmieniły, a które po prostu przesunęły się w górę lub w dół.
drugie, być jasne, co należy zrobić, jeśli lista jest dość statyczne (nie zmienia się cały czas), czy nie ma unikalną wartość związana z każdej pozycji ...
Don w ogóle używają :key
. Zamiast tego użyj into
w ten sposób:
(defn categorymanager []
(let [cats (re-frame/subscribe [:cats])]
(fn []
[:div
(into [:ul] (map #(vector :li (:text %)) @cats))])))
Zawiadomienie o tym, co się tutaj wydarzyło.Lista dostarczona przez map
jest złożona into
wektor into
. Na końcu nie widać żadnej listy. Po prostu zagnieżdżone wektory.
Ostrzeżenia o brakujących kluczach pojawiają się tylko w przypadku osadzenia elementu list
w czkawkę. Powyżej nie ma wbudowanego list
, tylko vectors
.
trzecie, jeśli lista jest naprawdę dynamiczny ...
Dodaj unikalny key
każdej pozycji (unikatowy rodzeństwa jest standardem). W podanym przykładzie, sama :text
jest wystarczająco dobry key
(zakładam, że jest niepowtarzalny):
(defn categorymanager []
(let [cats (re-frame/subscribe [:cats])]
(fn []
[:div
[:ul (map #(vector :li {:key (:text %)} (:text %)) @cats)]])))
To map
spowoduje list
który jest 1 parametr do [:ul]
. Kiedy Reagent/React widzi, że list
będzie chciał zobaczyć keys
na każdym elemencie (pamiętasz, że listy różnią się od wektorów w czapce odczynnika) i wydrukuje ostrzeżenia na konsolę, były one niedostępne keys
.
Dlatego musimy dodać key
do każdej pozycji z list
. W powyższym kodzie nie dodajemy :key
za pośrednictwem metadanych (chociaż można to zrobić w ten sposób, jeśli chcesz), a zamiast tego dostarczamy key
poprzez 1. parametr (z [:li]
), który zwykle przenosi również dane stylu.
Wreszcie - część 1 NIE używaj map-indexed
jak sugeruje się w innej odpowiedzi.
key
powinna być unikalną wartością związaną z każdym przedmiotem. Dołączenie jakiejś liczby całkowitej arb nie przynosi pożytku - cóż, pozbędzie się ostrzeżeń w konsoli, ale powinieneś użyć powyższej techniki, jeśli tego chcesz.
Wreszcie - część 2 nie ma różnicy między map
i for
w tym kontekście.
Oba skutkują list
. Jeśli ten list
ma klucze, to nie ma ostrzeżenia. Ale jeśli brakuje kluczy, to wiele ostrzeżeń. Ale sposób, w jaki utworzono listę, nie wchodzi w jej skład.
Ta wersja for
jest prawie taka sama jak wersja map
. Niektórzy mogą go wolą:
(defn categorymanager []
(let [cats (re-frame/subscribe [:cats])]
(fn []
[:div
[:ul (for [i @cats] [:li {:key (:text i)} (:text i)])]])))
który może być także napisane przy użyciu metadanych takiego:
(defn categorymanager []
(let [cats (re-frame/subscribe [:cats])]
(fn []
[:div
[:ul (for [i @cats] ^{:key (:text i)}[:li (:text i)])]])))
Finally - część 3
mapv
jest problem, ponieważ od tej kwestii: https://github.com/Day8/re-frame/wiki/Using-%5Bsquare-brackets%5D-instead-of-%28parentheses%29#appendix-2
Perły od twórcy re-frame! Dziękuję Ci!!! –
Podczas reddit twoja odpowiedź została opisana jako epicka. :-) –