Dummy question - can I set react keys like this? [:div {:key 123}]
So will a scaled up version of
[:div
(for [k (get-thousands-of-keys)]
^{:key k} [some-complex-component (get-params k)])]
be more efficient in terms of re-rendering a single item than
(into [:div]
(map (fn [k]
[some--complex-component (get-params k)]))
(get-thousands-of-keys))
?Probably the difference is quite small if the order and the set of items is same for each render. Difference is most obvious if React has to add some DOM elements between old elements or such.
Ah, right. So reordering would be more efficient as well, it makes sense.
FWIW this benchmark is useful comparison for keyed vs. non-keyed differences https://krausest.github.io/js-framework-benchmark/2021/table_chrome_89.0.4389.72.html
keyed is faster for certain ops and non-keyed for others
so depending on how your items change it might be better to use one or the other. it can be significant.
Hold old. How can you compare? Between keyed and non-keyed tables, React versions are different. And Reagent is not even present in the latter.
just compare react. the version difference doesn't matter much.
There is separate implementation for keyed / non-keyed version. Reagent only has keyed implementation for that benchmark.
nowadays the implementations are pretty good across the board so keyed is pretty much a no brainer in all situations
Then the results are very strange. Swapping two rows without keys is more than an order of magnitude faster than with keys.
Keys have another disadvantage - it's not always easy to come up with the right key given a set of complex props.
yes, because of the underlying dom operation it does
non-keyed it changes the text of 2 dom elements but doesn't move them. so the browser doesn't need to perform a layout/style recacluation
for keyed it moves the dom elements and it needs to recalc the whole list in the worst case
Then why keyed would be a no-brainer, given that you still have to put extra responsibility on yourself to select the right key generation algorithm?
well most of the time you have some natural keys anyways
the into
thing is pretty much the worst thing you can do performance wise but it is the only option to go non-keyed
so that will almost certainly lose to a keyed impl
Suppose I have a collection of entities with IDs and a bunch of text values that I need to display. That ID is natural, yes, so it makes sense to set it as a key. But those text values can change without any change to the ID. Won't using ID as a key prevent the items from being re-rendered when one of the text values changes? I definitely remember falling into a version of such a trap before, where there was an obvious natural key that ended up preventing the components from being re-rendered when needed.
No
but if you look at inferno for example the difference in swap rows for keyed/non-keyed is much smaller
so it is much more an artifact of how react handles this not general
no the key only controls ordering, it does not affect other updates
Id controls the component lifecycle and is used for DOM reconcilation, if component properties change, it will be re-rendered, key doesn't matter.
Hmm, perhaps I'm much more confused than I thought. Thanks for the info, I'll experiment with it.
> Won't using ID as a key prevent the items from being re-rendered when one of the text values changes? it will still re-render, but the way it changes the DOM and the component lifecycle may be different. keys are especially useful if you're trying to manage input/focus/component state/etc. in a list - you don't want React to blow away your DOM and component state of of all your rows if some data changes and you swap two rows
IIRC yes.
And just in case - if that comes up because of for
or something similar, you can avoid using keys altogether by just (into [] ...)
.
Do array indices become the key?
... as regarded by reagent?
When you're using a vector, there's no longer a need for keys.