reagent

2023-03-01T11:09:23.714149Z

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-himik 2023-03-01T11:17:59.873129Z

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-himik 2023-03-01T11:18:18.406039Z

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

2023-03-01T11:56:01.010739Z

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

p-himik 2023-03-01T11:56:47.149549Z

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

jcb 2023-03-01T13:58:39.594019Z

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.

rolt 2023-03-01T15:56:03.754009Z

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

rolt 2023-03-01T15:57:24.928329Z

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

jcb 2023-03-01T16:10:19.805709Z

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

rolt 2023-03-01T16:13:31.012849Z

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

rolt 2023-03-01T16:14:15.246869Z

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)

jcb 2023-03-01T16:22:42.470409Z

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

rolt 2023-03-01T17:21:56.917959Z

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