Closed khmelevskii closed 1 year ago
You can use react/useEffect
and react/useLayoutEffect
to build it yourself. The downside is you won’t have the same syntax as use-effect
and use-layout-effect
.
You could build your own macro that used a def that was determined the way above. Example
(def use-isomorphic-layout-effect*
(if (= (type js/window) "undefined")
react/useEffect
react/useLayoutEffect))
(defmacro use-isomorphic-layout-effect ,,,)
Yes, I understand that I can do something like this. I prefer to have use-isomorphic-layout-effect
with the same interface as use-effect
.
Because of use-effect
and use-layout-effect
are macro, I can't create use-isomorphic-layout-effect
based on them and I need to use react versions as you described above. But it means that I need to copy some of helix code https://github.com/lilactown/helix/blob/master/src/helix/hooks.cljc#L189.
I'm not sure that it's a good idea to add custom hook to helix and I'm also not sure that helix need to have additional hooks with the same interface but as functions(not macros). So, I think I will copy part of helix code to do my own macro.
If you don't have any other ideas for this case I can close ticket
I think it is possible to write macro that invokes cljs.analyzer.api
to grab compiler options and emit different macros depending on the active compilation target.
I will try to make a proof of concept soon.
This seems to work well enough.
(ns demo.hooks
#?(:clj (:require [cljs.analyzer.api :as analyzer])
:cljs (:require-macros [demo.hooks])))
#?(:clj
(defmacro use-isomorphic-effect [& body]
;; Although shadow offers a variety of targets, the CLJS compiler itself
;; has roughly the following distinctions:
;;
;; "default" - browser
;; "nodejs" - node runtime
;; "webworker" - web worker
;;
;; We assume that a target of Node is code intending to run on a server.
(let [effect-hook (if (= "nodejs"
(get-in (analyzer/get-options)
[:closure-defines 'cljs.core/*target*]))
'helix.hooks/use-effect
'helix.hooks/use-layout-effect)]
`(~effect-hook ~@body))))
This is very useful. Thank you @rome-user !
This seems to work well enough.
(ns demo.hooks #?(:clj (:require [cljs.analyzer.api :as analyzer]) :cljs (:require-macros [demo.hooks]))) #?(:clj (defmacro use-isomorphic-effect [& body] ;; Although shadow offers a variety of targets, the CLJS compiler itself ;; has roughly the following distinctions: ;; ;; "default" - browser ;; "nodejs" - node runtime ;; "webworker" - web worker ;; ;; We assume that a target of Node is code intending to run on a server. (let [effect-hook (if (= "nodejs" (get-in (analyzer/get-options) [:closure-defines 'cljs.core/*target*])) 'helix.hooks/use-effect 'helix.hooks/use-layout-effect)] `(~effect-hook ~@body))))
Not sure if this works with all shadow-cljs targets that users may want to fallback to use-effect
, but I think this is easily testable and manageable in peoples' projects for now. Thank you for this!
I'm trying to create
use-isomorphic-layout-effect
based onuse-effect
anduse-layout-effect
. Something like thisBut I can't do this because
use-effect
anduse-layout-effect
are macro