with useSyncExternalStorage in React 17/18 (and a shim on npm) I'm tempted to remove the https://github.com/lilactown/helix/blob/35127b79405e5dff6d9b74dfc674280eb93fab6d/src/helix/hooks.cljc#L327 I wrote 4 years ago to cover some of the missing features in the original use-subscription. Also, holy moly, I wrote that 4 years ago; feels like a year or two ago...
useSyncExternalStorage is what I use to temporarily integrate re-frame with the helix app I have at work
maybe deprecate it in the next release of helix then remove when you cut a 0.3 release? that way the people who may possibly be using your hook can know to move it into their own code soon
@Jakub would the following hook satisfy your no. 1? I wouldn’t mind some code review.
(defn connect-atom
([atm]
(connect-atom atm [] identity))
([atm keypath]
(connect-atom atm keypath identity))
([atm keypath f]
(let [watch-key (js/Object.)
[state set-state] (hooks/use-state (f (get-in @atm keypath)))]
(hooks/use-effect
:once
(add-watch atm watch-key
(fn [_k _r o n]
(let [o (f (get-in o keypath o))
n (f (get-in n keypath n))]
(when
(not= o n)
(set-state n)))))
#(remove-watch atm watch-key))
[state set-state])))
Makes sense, it feels like it is in a bit of an odd middle layer position. From a user's perspective it is to low-level to be used directly. From an integrator's perspective it makes sense to skip it and use lower-level primitives like useSyncExternalStorage directly for maximum control.
From a user perspective I would find useful if a library provided me with two hooks: 1. subscribe to an atom for plain react interop 2. subscribe to reagent/re-frame subscription when integrating into existing app - it is straightforward to do naive integration, but that does account for things like batching and tearing, so it would be nice to rely on a proper implementation