helix

dominicm 2024-07-18T18:24:39.971199Z

If I promise to be a good boy and only use it for small values, what's the best way to do use-memo with cljs.core/=?

dominicm 2024-07-18T18:26:13.736879Z

My context: I have a small list of ids I'm pulling out of a pyramid db that feeds into a HTTP request that I'd like to prevent the HTTP request from re-firing unnecessarily.

dominicm 2024-07-19T09:18:08.458789Z

The db is central for the application, so quite frequently 😓 hence why the cheap computation seems ok.

lilactown 2024-07-19T21:25:26.238579Z

here's a hook that we use (but try not to abuse)

(defn use-stable-identity
  "Caches `x`. When a new `x` is passed in, returns new `x` only if it is
  not structurally equal to the previous `x`.
  Useful for optimizing `use-effect`, `use-memo` et. al. when you have two
  values that might be structurally equal but referentially different."
  [x]
  (let [-x (react/useRef x)
        ;; if they are equal, return the prev one to ensure ref equality
        x' (if (= x (.-current -x))
               (.-current -x)
               x)]
    ;; Set the ref to be the last value that was succesfully used to render
    (react/useEffect (fn []
                       (set! (.-current -x) x)
                       js/undefined)
                     #js [x'])
    x'))

lilactown 2024-07-19T21:28:20.656859Z

you can also essentially copy this pattern into whatever hook/component you're building

(defnc my-component
  []
  (let [data (p/pull (use-db) ,,,)
        *prev-data (hooks/use-ref data)]
    (hooks/use-effect [data] (reset! *prev-data data))
    (hooks/use-effect [data]
      (when (not= @*prev-data data)
        ;; do http request
        ))
    ,,,))

dominicm 2024-07-19T21:44:24.354209Z

Oh neat, that's perfect thank you. Refs always go over my head. I need to get my head around them.

hifumi123 2024-07-18T20:59:00.097759Z

So in short you have an array of primitive values (numbers or strings, presumably) that you want to memoize?

dominicm 2024-07-18T20:59:32.531499Z

Yep. So the array reference stays the same for comparison of depa

hifumi123 2024-07-18T21:01:58.032069Z

In this case you'd want to memoize the computation of the array, rather than the array itself

hifumi123 2024-07-18T21:02:13.443569Z

AFAIK useMemo doesn't offer a custom comparison function, so the next best thing is to perform the memoization elsewhere

dominicm 2024-07-19T04:35:48.285889Z

Maybe usememo is the wrong tool. And I am making the assumption that the array needs to be a stable reference which might not be true.

hifumi123 2024-07-19T04:50:26.352259Z

How often does the corresponding data change? You can also consider caching the responses after fetching once. Some libraries like swr and react-query are able to do this automatically, and they expose a lot of functionality for validation and refetching