This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-12
Channels
- # announcements (1)
- # aws (1)
- # babashka (63)
- # beginners (108)
- # calva (12)
- # cider (6)
- # cljdoc (2)
- # cljsrn (33)
- # clojure (150)
- # clojure-europe (28)
- # clojure-nl (13)
- # clojure-spain (1)
- # clojure-spec (8)
- # clojure-uk (25)
- # clojurescript (16)
- # conjure (7)
- # cursive (7)
- # datomic (15)
- # duct (2)
- # eastwood (2)
- # figwheel (1)
- # figwheel-main (1)
- # fulcro (6)
- # graalvm (1)
- # graalvm-mobile (1)
- # helix (6)
- # honeysql (23)
- # integrant (6)
- # introduce-yourself (4)
- # jobs (10)
- # lsp (132)
- # malli (4)
- # meander (1)
- # membrane (1)
- # off-topic (223)
- # pathom (23)
- # pedestal (3)
- # re-frame (18)
- # reagent (13)
- # releases (1)
- # remote-jobs (2)
- # shadow-cljs (68)
- # tools-deps (217)
- # vim (19)
- # xtdb (79)
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.
Hm seems like I want track
actually?
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.
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
.And, of course:
(defn get-item-by-id [id]
(let [idx (@id->item-idx id)
data @data]
(assert (vector? data))
(nth data idx)))
Point is I do stuff on every mouse movement