refactor: make react hooks compatible with cljs builtin types

This commit is contained in:
rcmerci
2025-01-07 14:35:59 +08:00
parent e9a5235aa3
commit fd0bc933e9
3 changed files with 54 additions and 2 deletions

View File

@@ -122,6 +122,7 @@
frontend.handler.route route-handler
frontend.handler.search search-handler
frontend.handler.ui ui-handler
frontend.hooks hooks
frontend.idb idb
frontend.loader loader
frontend.mixins mixins

View File

@@ -55,6 +55,7 @@
[frontend.handler.route :as route-handler]
[frontend.handler.ui :as ui-handler]
[frontend.handler.whiteboard :as whiteboard-handler]
[frontend.hooks :as hooks]
[frontend.mixins :as mixins]
[frontend.mobile.intent :as mobile-intent]
[frontend.mobile.util :as mobile-util]
@@ -2750,11 +2751,11 @@
(let [[result set-result!] (rum/use-state nil)
repo (state/get-current-repo)
[status-history time-spent] result]
(rum/use-effect!
(hooks/use-effect!
(fn []
(p/let [result (db-async/<task-spent-time repo (:db/id block))]
(set-result! result)))
[(:db/id (:logseq.task/status block))])
[(:logseq.task/status block)])
(when (and time-spent (> time-spent 0))
[:div.text-sm.time-spent.ml-1
(shui/button

View File

@@ -0,0 +1,50 @@
(ns frontend.hooks
"React custom hooks."
(:refer-clojure :exclude [ref deref])
(:require [datascript.impl.entity :refer [Entity]]
[rum.core :as rum]))
(defn- safe-dep
"js/React use `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)
:else
(throw (ex-info (str "Not supported dep type:" (type dep)) {:dep dep})))))
(defn use-memo
([f] (rum/use-memo f))
([f deps] (rum/use-memo f (map safe-dep deps))))
(defn use-effect!
([setup-fn] (rum/use-effect! setup-fn))
([setup-fn deps] (rum/use-effect! setup-fn (map safe-dep 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))))
(defn use-callback
([callback] (rum/use-callback callback))
([callback deps] (rum/use-callback callback (map safe-dep deps))))
;;; unchanged hooks, link to rum/use-xxx directly
(def use-ref rum/use-ref)
(def create-ref rum/create-ref)
(def deref rum/deref)
(def set-ref! rum/set-ref!)
(def use-state rum/use-state)
(def use-reducer rum/use-reducer)