Browse Source

refactor: add memo-deps to wrap hook-deps

rcmerci 11 months ago
parent
commit
051cadaf6a
1 changed files with 16 additions and 29 deletions
  1. 16 29
      src/main/frontend/hooks.cljs

+ 16 - 29
src/main/frontend/hooks.cljs

@@ -1,48 +1,35 @@
 (ns frontend.hooks
   "React custom hooks."
   (:refer-clojure :exclude [ref deref])
-  (:require [datascript.impl.entity :refer [Entity]]
-            [goog.functions :as gfun]
+  (:require [goog.functions :as gfun]
             [rum.core :as rum]))
 
-(defn- safe-dep
-  "js/React uses `js/Object.is` to compare dep-value and its previous value.
-  Some cljs built-in types(keyword, symbol, uuid) would not be identical, even they are value-equal."
-  [dep]
-  (if (contains? #{"string" "number" "boolean" "null"} (goog/typeOf dep))
-    dep
-    (cond
-      (or (keyword? dep)
-          (symbol? dep)
-          (uuid? dep))
-      (str dep)
-
-      (instance? Entity dep)
-      ;; NOTE: only :db/id is considered, without taking the entity-db into account
-      ;; so, same entity-id but different db will be "equal" here
-      (:db/id dep)
-
-      (implements? IHash dep) (hash dep)
-
-      :else
-      (throw (ex-info (str "Not supported dep type:" (print-str (type dep))) {:dep dep})))))
+(defn- memo-deps
+  [equal-fn deps]
+  (let [equal-fn (or equal-fn =)
+        ^js deps-ref (rum/use-ref deps)]
+    (when-not (equal-fn (.-current deps-ref) deps)
+      (set! (.-current deps-ref) deps))
+    (.-current deps-ref)))
 
 (defn use-memo
-  [f deps]
-  (rum/use-memo f (map safe-dep deps)))
+  [f deps & {:keys [equal-fn]}]
+  (rum/use-memo f #js[(memo-deps equal-fn deps)]))
 
 (defn use-effect!
   "setup-fn will be invoked every render of component when no deps arg provided"
   ([setup-fn] (rum/use-effect! setup-fn))
-  ([setup-fn deps] (rum/use-effect! setup-fn (map safe-dep deps))))
+  ([setup-fn deps & {:keys [equal-fn]}]
+   (rum/use-effect! setup-fn #js[(memo-deps equal-fn deps)])))
 
 (defn use-layout-effect!
   ([setup-fn] (rum/use-layout-effect! setup-fn))
-  ([setup-fn deps] (rum/use-layout-effect! setup-fn (map safe-dep deps))))
+  ([setup-fn deps & {:keys [equal-fn]}]
+   (rum/use-layout-effect! setup-fn #js[(memo-deps equal-fn deps)])))
 
 (defn use-callback
-  [callback deps]
-  (rum/use-callback callback (map safe-dep deps)))
+  [callback deps & {:keys [equal-fn]}]
+  (rum/use-callback callback #js[(memo-deps equal-fn deps)]))
 
 ;;; unchanged hooks, link to rum/use-xxx directly
 (def use-ref rum/use-ref)