I’m puzzling out how best to get current props available in an event handler. Example in thread.
(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] ...)})))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.
I believe this-as might be helpful here?
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.
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
Also don’t think that will work in an event handler.
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.
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?
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
Also, I think (r/props (r/current-component)) should be enough?
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?