2

In the clojurescript re-frame todomvc application we find the following snippet in the todomvc.views namespace.

(defn todo-list
  [visible-todos]
  [:ul.todo-list
   (for [todo  @visible-todos]
     ^{:key (:id todo)} [todo-item todo])])

Although I have read the Clojure chapter on metadata I don't quite understand the purpose of:

^{:key

in the snippet above. Please explain.

Alex Miller
  • 69,183
  • 25
  • 122
  • 167
nilo de roock
  • 4,077
  • 4
  • 34
  • 62

2 Answers2

4

The :key is what React needs when you have many items, so that they can be unique within the group. But the latest version of React does not need these keys. So if you use the latest versions of reframe / Reagent, just try without the :key metadata.

This metadata is equivalent to placing :key within the component. So for example what you have is equivalent to:

[todo-item {:key (:id todo)} todo]

Using the metadata approach is a convenience, which must in some cases be easier than the 'first key in props passed to the component' approach.

Here's more explanation.

Community
  • 1
  • 1
Chris Murphy
  • 6,411
  • 1
  • 24
  • 42
  • Interesting for the author of re-frame as well ! - Just found it in Reagent tutorial ... " The ^{:key item} part above isn’t really necessary in this simple example, but attaching a unique key to every item in a dynamically generated list of components is good practice, and helps React to improve performance for large lists. " – nilo de roock May 09 '16 at 09:47
1

^{:key (:id todo)} [todo-item todo] would be equivalent to (with-meta [todo-item todo] {:key (:id todo)}), see https://clojuredocs.org/clojure.core/with-meta

Reagent uses this to generate the corresponding react component with a key. Keys help React identify which items have changed, are added, or are removed. here is the explanation: https://reactjs.org/docs/lists-and-keys.html

Victor Gil
  • 41
  • 6