A minimalistic ClojureScript interface to React.js
achikin 2021-03-22T14:02:51.011300Z

Dummy question - can I set react keys like this? [:div {:key 123}]

p-himik 2021-03-23T10:09:53.012700Z

So will a scaled up version of

  (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)]))

juhoteperi 2021-03-23T10:12:24.012900Z

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.

p-himik 2021-03-23T10:13:27.013100Z

Ah, right. So reordering would be more efficient as well, it makes sense.

thheller 2021-03-23T10:14:53.013300Z

FWIW this benchmark is useful comparison for keyed vs. non-keyed differences

thheller 2021-03-23T10:15:06.013500Z

keyed is faster for certain ops and non-keyed for others

thheller 2021-03-23T10:16:44.013700Z

so depending on how your items change it might be better to use one or the other. it can be significant.

p-himik 2021-03-23T10:17:47.013900Z

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.

thheller 2021-03-23T10:18:39.014100Z

just compare react. the version difference doesn't matter much.

juhoteperi 2021-03-23T10:18:46.014300Z

There is separate implementation for keyed / non-keyed version. Reagent only has keyed implementation for that benchmark.

thheller 2021-03-23T10:20:58.014600Z

nowadays the implementations are pretty good across the board so keyed is pretty much a no brainer in all situations

p-himik 2021-03-23T10:21:29.014800Z

Then the results are very strange. Swapping two rows without keys is more than an order of magnitude faster than with keys.

p-himik 2021-03-23T10:21:48.015Z

Keys have another disadvantage - it's not always easy to come up with the right key given a set of complex props.

thheller 2021-03-23T10:21:53.015200Z

yes, because of the underlying dom operation it does

thheller 2021-03-23T10:22:48.015400Z

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

thheller 2021-03-23T10:23:07.015600Z

for keyed it moves the dom elements and it needs to recalc the whole list in the worst case

p-himik 2021-03-23T10:23:43.015800Z

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?

thheller 2021-03-23T10:24:49.016Z

well most of the time you have some natural keys anyways

thheller 2021-03-23T10:25:12.016200Z

the into thing is pretty much the worst thing you can do performance wise but it is the only option to go non-keyed

thheller 2021-03-23T10:25:44.016400Z

so that will almost certainly lose to a keyed impl

p-himik 2021-03-23T10:27:25.016600Z

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.

juhoteperi 2021-03-23T10:28:21.016800Z


thheller 2021-03-23T10:28:23.017Z

but if you look at inferno for example the difference in swap rows for keyed/non-keyed is much smaller

thheller 2021-03-23T10:28:37.017200Z

so it is much more an artifact of how react handles this not general

thheller 2021-03-23T10:29:02.017400Z

no the key only controls ordering, it does not affect other updates

juhoteperi 2021-03-23T10:29:02.017600Z

Id controls the component lifecycle and is used for DOM reconcilation, if component properties change, it will be re-rendered, key doesn't matter.

p-himik 2021-03-23T10:36:48.018Z

Hmm, perhaps I'm much more confused than I thought. Thanks for the info, I'll experiment with it.

lilactown 2021-03-23T14:53:04.018500Z

> 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

p-himik 2021-03-22T14:03:30.011400Z

IIRC yes.

p-himik 2021-03-22T14:04:04.011600Z

And just in case - if that comes up because of for or something similar, you can avoid using keys altogether by just (into [] ...).

chepprey 2021-03-22T20:05:44.011800Z

Do array indices become the key?

chepprey 2021-03-22T20:06:17.012Z

... as regarded by reagent?

p-himik 2021-03-22T20:08:39.012200Z

When you're using a vector, there's no longer a need for keys.