At first , itβs clear why you are using key ...
A key supply for each item in the list is useful when this list is quite dynamic - when new items in the list are regularly added and removed, especially if the list is long and items are added / removed near the top of the list.
keys can provide more performance because they allow React to redraw these pluggable lists more efficiently. Or, more precisely, it allows React to avoid redrawing elements that have the same key as the last time, and which have not changed and which are simply shuffled up or down.
Second , itβs clear what you should do if the list is pretty static (it doesn't change all the time) OR if there is no unique value associated with each element ...
Do not use :key at all. Instead, use into as follows:
(defn categorymanager [] (let [cats (re-frame/subscribe [:cats])] (fn [] [:div (into [:ul] (map #(vector :li (:text %)) @cats))])))
Pay attention to what happened here. The list provided by map is folded into vector [:ul] . At the end of it there is no list. Just nested vectors.
You only get warnings about missing keys when you insert list into hiccups. There is no inline list above, just vectors .
Third , if your list is really dynamic ...
Add a unique key to each element (unique siblings). In the above example itself :text is good enough key (I assume it is unique):
(defn categorymanager [] (let [cats (re-frame/subscribe [:cats])] (fn [] [:div [:ul (map
That map will lead to list , which is the first parameter for [:ul] . When Reagent / React sees that list , it will want to see the keys for each element (remember that the lists are different from the vectors in the hiccup reagent) and to print warnings on the console there were keys that would be absent.
Therefore, we need to add key to each list element. In the above code, we do not add :key through metadata (although you can do it this way if you want), and instead we supply key through the 1st parameter ( [:li] ), which usually also contains style data.
Finally - Part 1 DO NOT use map-indexed as suggested in another answer.
key must be a unique value associated with each element. Attaching some integer arb is nothing useful - well, it gets rid of warnings in the console, but you should use the into technique above if that's all you want.
Finally, part 2 in this context there is no difference between map and for .
Both of them lead to list . If this list has keys, then no warnings. But if there are no keys, then there are many warnings. But the way to create a list is not in it.
So, this for version is pretty much like the map version. Some may prefer this:
(defn categorymanager [] (let [cats (re-frame/subscribe [:cats])] (fn [] [:div [:ul (for [i @cats] [:li {:key (:text i)} (:text i)])]])))
What can also be written using metadata, for example:
(defn categorymanager [] (let [cats (re-frame/subscribe [:cats])] (fn [] [:div [:ul (for [i @cats] ^{:key (:text i)}[:li (:text i)])]])))
Finally - Part 3
mapv is a problem because of this problem: https://github.com/Day8/re-frame/wiki/Using-%5Bsquare-brackets%5D-instead-of-%28parentheses%29#appendix-2