Fork me on GitHub

So what would be best practice in Rum?


  [goog.object :as gob]

(gob/set js/window "foo" "bar")


(let [dom (.getElementById js/document "my-video")]
  (set! (.-playBackRate dom) 0.6))


I've actually experimented with both and have still been unsuccessful


Am I right in the assumption that I need to do this within the component?


@grounded_sage you would want to do those things within a component. Try to use rum/ref-node and :did-mount mixin


I think I need to take the time to really sit down and read Rum. Problem is I don't really know ha that well or plain React :p


@nxqd @grounded_sage Don't use ref-node, they're basically deprecated in React, use function callbacks instead. (`:ref (fn [dom-node-or-nil] ...))`


@rauh: is there an example of something like this in the wild? I'll sit down when at a computer and have a play. But I'm just looking at it now and think I have no idea where I would put that.


See the two links.


@rauh Thanks for pointing out


Thanks! I feel like I am asking nooby questions but it definitely helps me feel less of a burden when other people are also getting help from the questions.


@grounded_sage rum does not change how you interop with vanilla js from cljs. Setting attribute value on a dom node - is an interop, and I'd follow advice of the cljs maintainer here, and use goog.obj/set. Where to do this in your - is another story, this is where the ref-node and other React rules and best practices come in.


Yea the problem is that CLJ is my first serious language coming from a light play with JS literally up to objects and not much into it. So my knowledge of JS and React vanilla as a whole is somewhat lacking so it's usually trial by error for me. CLJS interop is pretty easy to get but then when it comes to how things work with the vdom in such cljs libraries my google skills turn up little reference material.


I'll take some time soon to play around with all the suggestions and report back within a few days :)


setting video playback rate is not a trivial(?) usecase though, because usually you deal with controlled components, where everything you need is stored in some atom, and you just re-render everything from scratch on any change. here, in video case, you need to "hot swap" value on a dom node, to avoid restarting video, and it does not look pretty in the code (or look like usual rum code)


writing an example now


    [goog.object :as gob]))

(rum/defcs video
  < {:will-mount
     (fn [state]
       (let [video (atom nil)
             playback-rate (atom 1.0)]
         (add-watch playback-rate ::playback-rate
           (fn [_ _ _ n]
             (when-let [node @video]
               (gob/set node "playbackRate" n))))
         (assoc state
           ::video video
           ::playback-rate playback-rate)))}

  (let [set-ref!  #(reset! (::video state) %)
        set-rate! #(reset! (::playback-rate state) %)]
      {:ref set-ref!
       :width 480 :controls true}
      [:source {:src ""
                :type "video/webm"}]]
      [:button {:onClick #(set-rate! 0.5)} "speed 0.5"]
      [:button {:onClick #(set-rate! 1.0)} "speed 1.0"]
      [:button {:onClick #(set-rate! 1.5)} "speed 1.5"]]]))


calling gob/set inline triggers react errors about "ref being accessed in render method"


Wow thanks so much! Strange!! I always seem to find myself in he edge cases of what people haven't done yet and here I am thinking this should be easy haha


Not that it haven't been done before, it just makes up like 1% of ui use cases I dealt with (I didn't do much animation yet, and animation will probably look like this video example too)


Yea that's what I mean. Either haven't been done or not publicly available on GitHub or talked about. I do plan on using Greensixk animations in future. Will be interesting once that happens too