reagent

wevrem 2024-11-21T01:17:44.503469Z

I’m puzzling out how best to get current props available in an event handler. Example in thread.

wevrem 2024-11-21T01:18:03.197949Z

(defn component [props]
  (let [handle-key (fn [e]
                     ;; Need current props, but can't use `props`, those will
                     ;; be out-of-date. 
                     ;; Want to use `(r/props this)`, but how do we
                     ;; get `this`?
                     )
        ;; Want to use this handler, but will it be properly removed?
        handle-key-II (fn [this]
                        (fn [e]
                          ;; Here we could do (r/props this).
                          ))]
    (r/create-class
     {:display-name "my-component"

      :component-did-mount
      (fn [this]
        ;; if we need them, can access current props with `(r/props this)`.
        (.addEventListener js/document "keydown" handle-key)
        (.addEventListener js/document "keydown" (handle-key-II this)))

      :component-will-unmount
      (fn [this]
        (.removeEventListener js/document "keydown" handle-key)
        ;; Will this remove actually work? It's not the same function that was
        ;; added above during component mount.
        (.removeEventListener js/document "keydown" (handle-key-II this)))

      :reagent-render
      (fn [props] ...)})))

wevrem 2024-11-21T01:26:29.827629Z

The code above is showing both handle-key and an alternative, handle-key-II, but I’m not wanting to use both at the same time. The first one, handle-key will properly add and remove during the component lifecycle calls, but it has no way to access the current component properties. The second one is how I would normally deal with this, by closing around the inputs I need, but then it won’t be properly removed. (I think). I was getting a funny error and realized that I was adding (handle-key-II this) as a listener, but removing just handle-key-II. That mismatch obviously wasn’t removing my listeners and then I started getting strange errors. I haven’t actually tested what happens if I try to both add and remove (handle-key-II this) but I suspect it won’t work because even though they look the same, they aren’t really equivalent. But I will test it and see. Just wondering if anyone out there has encountered the same oddity and has a solution for it.

liebs 2024-11-21T01:34:52.434779Z

I believe this-as might be helpful here?

wevrem 2024-11-21T01:54:28.064199Z

Is it? Inside my handler, this will be some DOM element representing the HTML document. I’m trying to get to my reagent component and its current properties.

liebs 2024-11-21T01:55:59.168739Z

Yeah true, what about r/current-component? I know there's some trick I've used for this but I don't recall specifics sadly

wevrem 2024-11-21T02:15:47.821249Z

Also don’t think that will work in an event handler.

wevrem 2024-11-21T02:17:54.826179Z

My solution, thought it feels very hacky, was to define ref-this (atom nil) in the outer let, and then inside component-did-mount I (reset! ref-this this). Then in my handler function I can access @ref-this and call (r/props @ref-this). It works so far, but I’m feeling like there should be a better way to accomplish.

liebs 2024-11-21T03:19:18.553979Z

sorry, I was on my phone previously so it was hard to get a good look at your example. But I was thinking about how I've handled similar things before and I think I used the :constructor of r/create-class?

liebs 2024-11-21T03:23:44.938109Z

in that function you get this and props . Also, not really a browser native solution, but goog.events has listeners that return unique keys so that you can unlisten to specific events

liebs 2024-11-21T03:25:49.708789Z

Also, I think (r/props (r/current-component)) should be enough?

wevrem 2024-11-21T04:07:34.447979Z

I’m going to try the :constructor, didn’t know about that one. Thanks for that. The reason I’m doubtful about current-component is because I think calling it from inside an event handler that was registered on js/document won’t get me back to the original component, right?