using clojurescript with react, instead of component-did-mount I want only when a component has focus on and it is on screen, not when it mounts: So (keyboard-listener-on) is only active when focus is on please
(defn bool-field [{:keys [field-id input-data form-messages current-page index regenerate-display-fields on-submit]}]
(let [text-val (r/atom (:value (get input-data (keyword field-id))))]
(r/create-class
{:component-did-mount (fn [_this]
(println (str "binding start " field-id))
(keyboard-listener-on!))
:component-will-unmount (fn [_this]
(println (str "unmount " field-id))
(keyboard-listener-off!))
:reagent-render (fn [{:keys [field-id form-messages on-submit regenerate-display-fields
field index theme-data current-page input-data]}]
[v-box
:width "100%"
:align :center
:justify :center
:children [...]])})))That's a more generic problem of JS - not even React, let alone Reagent. So I'd start with researching how to do it in JS and then proceed with adapting it for React and replicating it in CLJS+Reagent.
There might be some React components that do the first two steps for you.
https://github.com/streamich/react-use/blob/master/docs/useIntersection.md
any idea how I implement this in my code? Should I maybe have asked in beginners?
useIntersection is a hook, and Reagent documents how to use hooks: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks
I've come across an issue that I've never dealt with before. I'm trying to use wavesurfer.js in Reagent - it is a javascript object that binds to a dom component which has to be present before it loads, and then provides a waveform on a canvas and various utilities to interact with it. However, I can't figure out how to make it play nicely within react and maintain a reference to it for control and layout purposes. The following code infinitely creates the canvas - what am I missing?
(defn wave-component [id audio]
(with-let [!container (atom nil)
wave (atom nil)
load (fn [] ^js (.load @wave audio))
]
[:div.outer
[:div {:id id
:ref (fn [el] (reset! !container el))
:style {:height "100px" :width "1000px" :background-color "black"}
}]
(when @!container
(reset! wave (wavesurfer/create #js {:container (str "#" id)
:waveColor "violet"
:progressColor "purple"
:backend "MediaElement"
}))
(load)
)
]
)
)
I've got it working in other ways using multiple defns which works fine but then I lose the ability to control playback as I don't have a reference to the object outside of its definition.!container should be a clojure.core/atom and not a reagent.core/atom
otherwise you're re-rendering the component when the ref is set, which may change the ref, which re-render the component, etc
I see, thanks you for taking the time to answer. However, this way only the container div renders, not the waveform.
why don't you move the (reset! wave (wavesurfer/create ... to the :ref function ?
i can't see where the value of !container is actually needed in your snippet, you could even put that call before the "hiccup" vector (probably not)
ah yes, fair enough, that works well. Thanks again!
actually i'm not sure why you'd need waveeither, i guess you could get rid of those atoms and move this whole create + load function to the component-did-mount and component-did-update lifecycle methods