LearnAPI Reference
Guide: Keys

Keys

:replicant/key can be used to uniquely identify an element among its siblings. This can help Replicant make fewer DOM operations by moving a node instead of removing it, only to recreate it and insert it in a different position.

The classic (as in, used in React since 2013) example of explicit keying an element is when you have a list of elements of the same tag name:

;; Render 1
[:ul
 (for [fruit ["Banana" "Apple" "Orange"]]
   [:li fruit])]

;; Render 2
[:ul
 (for [fruit ["Apple" "Orange" "Banana"]]
   [:li fruit])]

Intuitively we perceive these two renders as reorderings. Replicant, on the other hand, sees li elements that have the wrong text content. In this case, Replicant would perform createTextNode and replaceChild three times.

Using a key can help Replicant understand the semantic difference better:

;; Render 1
[:ul
 (for [fruit ["Banana" "Apple" "Orange"]]
   [:li {:replicant/key fruit} fruit])]

;; Render 2
[:ul
 (for [fruit ["Apple" "Orange" "Banana"]]
   [:li {:replicant/key fruit} fruit])]

In this case, Replicant would only perform a single DOM operation: move the first li element to the end of the list. :replicant/key can be anything, not just strings like in this example.

It’s worth noting that :replicant/key is a double-edged sword. It can reduce the number of DOM operations needed. At the same time it imposes more constraints which can make Replicant’s rendering algorithm less efficient.

Same same, but different

It’s helpful to understand what Replicant considers to be “the same” node before deciding to add a key. Any two elements currently in the same position with the same tag name and same key are considered to be reusable — meaning that Replicant will perform the necessary changes to turn the existing node into whatever is occupying its space in the current hiccup.

This means that if you have a node whose children all have different tag names, you don’t need keys. If you don’t have life-cycle hooks, transitions, or stateful elements like form fields or elements with contenteditable, you don’t need explicit keys.

In short: there’s no need to proactively add :replicant/key.