Fork me on GitHub
#reagent
<
2021-07-12
>
Pepijn de Vos10:07:11

What would be the correct approach to cache values or create some sort of index? I have a O(N) thing that I don't want to run on every update, but I can maintain a map to turn it into a single lookup. My concern is that manually maintaining an index could be a bit fragile.

p-himik10:07:58

A reaction.

p-himik10:07:10

Assuming your thing is in a ratom.

Pepijn de Vos10:07:11

Hm seems like I want track actually?

Pepijn de Vos10:07:34

Wait no that would not work... so I have a drag & drop thing that updates the state but that's not a meaningful update for the index function, but if I use a track it'd reevaluate the function every time the onDrag handler is called, which is the thing I'm trying to avoid.

p-himik10:07:11

I think that track is identical to reactions (it uses a reaction itself) with one small difference - if you reuse the same fn between the renders (i.e. the very same object and not just the same definition) then the internal reaction will be cached. > I have a drag & drop thing that updates the state but that's not a meaningful update for the index function Create a chain of reactions where each extracts only the relevant layer of info from the data. Suppose you have data like this:

[{:name "John", :id 1}
 {:name "Alex", :id 2}]
And you want to change "Alex" to "Alexander" without re-evaluating the index. So, do something like this:
(def data (reagent.core/atom [...]))

(def ordered-ids (reagent.ratom/reaction (mapv :id @data)))
(def id->item-idx (reagent.ratom/reaction (reduce-kv (fn [acc idx id]
                                                       (assoc acc id idx))
                                                     {} @ordered-ids)))
You have to use something like vector indices as an intermediate thing here - you can't build an id->item index if your drag-n-drop functionality changes item.

p-himik10:07:52

And, of course:

(defn get-item-by-id [id]
  (let [idx (@id->item-idx id)
        data @data]
    (assert (vector? data))
    (nth data idx)))

emccue15:07:25

Have you tried doing the O(N) thing every update?

emccue15:07:17

as long as you don't do stuff every keystroke, usually its fine

Pepijn de Vos13:07:00

Point is I do stuff on every mouse movement