Fork me on GitHub

@lilactown Thank you for Helix. One more reason (pun) to stay with clojurescript.

Emmanuel John18:12:27

How do I create a react hook to use with re-frame? I see an example but it’s incomplete. Here’s what I’ve tried so far:

(defn watch-ratom
  (let [tracker (rc/track! f)]
    #(rc/dispose! tracker)))

(defn use-sub [query]
  (let [subscription (hhooks/use-memo :auto-deps
                                      {:get-current-value (fn []
                                                            @(rf/subscribe query))
                                       :subscribe         watch-ratom})
        value (hhooks/use-subscription subscription)]
This doesn’t work as I’m ending up with an infinite re-render.


this channel is for the Helix library, you should try asking at #re-frame

Emmanuel John19:12:30

Actually, I believe this is appropriate for this channel as I’m writing hooks for use with helix. It’s more likely someone here has had to write some kind of use-sub for a reagent atom.


hey Emmanuel. this channel is fine to ask your question. Thanks wilker for trying to moderate, though, as we do get questions that are really better served by #reagent and #re-frame sometimes 🙂


first reaction is that I'm not sure your watch-ratom is correct


the f passed to watch-ratom is a callback that should be called when you want React to re-render, and I think in this case track! is going to synchronously call that function. that would explain why you're getting in an infinite loop


I think you need to close over the reaction returned by the subscribe and then track that


this is pretty close to what we use at work:

(let [reaction (hhooks/use-memo
                 (rf/subscribe query))
      sub (hhooks/use-memo
            {:get-current-value #(deref reaction)
             :subscribe (fn [f]
                          (let [tracker (r/track! #(f @reaction))]
                            #(r/dispose! tracker)))})]
   (hhooks/use-subscription sub))


let me know if that works or not. the use-subscription hook hasn't been used in production yet. I'm hoping that it's not due to that but it might also be worth trying React's use-subscription if you continue to have issues

Emmanuel John19:12:39

Oh I see. That worked for me!

Emmanuel John19:12:30

I saw that the callback doesn’t currently accept any argument which is why I was calling the function without the reaction

Emmanuel John19:12:46

I’m actually surprised that #(f @reaction) works even though f is a 0 arity function


yeah I suppose to be stricter, it should be:

(fn []
  @reaction ;; for tracking side effect


you could also use add-watch / remove-watch I think


the important thing is to not call f unless reaction has changed


using track! like we are might cause a double render on mount since the function passed to track! gets called on mount to figure out what reactions to track


#(f @reaction) works because JS functions don't enforce arity, which is different than Clojure. CLJS does have some static compile-time checks but it's a best effort kind of thing

Emmanuel John20:12:12

Gotcha. Thank you!


ah, cool, didn't realize Helix had integration docs with other react wrappers 👍