Fork me on GitHub
#reagent
<
2019-07-11
>
Alexis Vincent11:07:47

Hi guys, Im trying to build a lib and I need to be able to register a handler for dismount from within a reagent component, without being able to control the component call site. I want to be able to do something like this.

(defn component []
  (on-dismout #(js/console.log "dismounted"))
  (fn []
    [:div]))
I’ve tried a few things, but none of them are ideal. this kind of gets there
(defn on-dismount [f]
  (let [reaction (.-cljsRatom (r/current-component))]
    (ratom/add-on-dispose! reaction f)))
but cljsRatom is not defined on first render.
(.-isMounted (.-updater (r/current-component) ) (r/current-component)
requires me to register a polling service and won’t be particularly quick Anyone have an idea?

Alexis Vincent12:07:14

Perhaps something along the lines of this could work

(defn on-dismount [f]
  (let [a* (r/atom nil)]
    @a*
    (ratom/add-on-dispose! a* f)))
If I were to make a reaction, not a r/atom

Alexis Vincent12:07:18

This also kind of works

(defn on-dismount [f]
  (let [id (rand-int 1000)
        reaction (ratom/make-reaction (constantly true)
                                      :on-set (constantly nil)
                                      :on-dispose f)]
    @reaction
    reaction))

But the caller needs to keep derefing the return value, in render cycle

oconn12:07:12

Would a form-3 component using :component-will-unmount fit the usecase?

Alexis Vincent12:07:04

No 😕 I dont want to change how people write their components. This should be an easy addition, otherwise people will effectively need to “cleanup” after the lib

Alexis Vincent12:07:04

I have the (r/current-component), I’m wondering whether there are some internal methods to react that I could hook into

oconn12:07:05

Maybe a higher order component that creates a wrapper around the provided component that would be responsible for the cleanup?

Alexis Vincent12:07:34

yeah, thats the other way. But I’m trying to avoid nesting you get when you start to do that.

danielneal13:07:49

this is kind of an ideal use case for react hooks. If you were using hooks you’d be able to do it with a hook that was like (defn useDispose [f] (useEffect (fn [] (fn [] (f)) #js [])

oconn13:07:31

Yeah I was going to suggest that. Any known future support for hooks with reagent?

Alexis Vincent14:07:54

@danieleneal exactly. But reagent writes out components as react classes. So its not possible without a large refractor of reagent, or some not so pretty code in your components

Alexis Vincent14:07:24

with hooks now I think we could fall back to a much lighter wrapper of react and implement the reactions in a lib

danielneal14:07:05

yeah, I’ve been playing with hx, which is nice for hooks and closer react interop, but prob not much help for you now in reagent. Hard to say what the right call for you in this case is as it depends a lot on your code base and what you have planned for it.