Fork me on GitHub
#reagent
<
2023-03-01
>
M J11:03:23

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 [...]])})))

p-himik11:03:59

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.

p-himik11:03:18

There might be some React components that do the first two steps for you.

M J11:03:01

any idea how I implement this in my code? Should I maybe have asked in beginners?

p-himik11:03:47

useIntersection is a hook, and Reagent documents how to use hooks: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks

jcb13:03:39

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.

rolt15:03:03

!container should be a clojure.core/atom and not a reagent.core/atom

rolt15:03:24

otherwise you're re-rendering the component when the ref is set, which may change the ref, which re-render the component, etc

jcb16:03:19

I see, thanks you for taking the time to answer. However, this way only the container div renders, not the waveform.

rolt16:03:31

why don't you move the (reset! wave (wavesurfer/create ... to the :ref function ?

rolt16:03:15

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)

jcb16:03:42

ah yes, fair enough, that works well. Thanks again!

rolt17:03:56

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