ANNC: Here is a re-release of a hopefully instructive Reagent demo app, https://github.com/kennytilton/hiringagent/blob/master/README.md, a port of my https://github.com/kennytilton/matrix/tree/master/js/matrix JS https://kennytilton.github.io/whoishiring/. Main enhancement is a minor tweak to avoid CORS issues that would prevent the thing even from running in a dev environment. Years ago I guess browsers locked down loading files from a directory; this avoids doing that. Next up is an attempted port to reagent 1.0.
That was easy ^^^^. +1 on the backward compatibility! Tough question: are there any killer features I am missing by sticking with โbackwardsโ? Perusing the doc it seems 1.0 is about the segue to React hooks. I see also going that route is a bit slower. Did I just answer my own question? ๐
Hey, everyone. I'm new here.
Is this the right place to ask questions about specific problems we encounter when working with Reagent?
It sure is. Unless you're certain you're hitting a bug - then I'd just go straight to GitHub issues.
No, I'm not certain. Still relatively new to Clojure.
If you have a moment, take a look at the detailed description of the problem I have posted to Stack Overflow. I don't want to take the space here by copying and pasting the entire (lengthy) thing: https://stackoverflow.com/questions/63944323/problem-with-autocomplete-material-ui-react-reagent-clojurescript
Oh, you're in for a treat. CLJS + Reagent + Material UI is a goldmine of similar issues.
You write in the question: "Breaking in JS debugger, I see that inputRef.current is null"
The reason is most likely due to the way Reagent passes the properties around. It does js->clj
, more or less, and then clj->js
. It creates copies of objects. But if something wants to pass the result of Reagent/createRef
, which is just an object with a single key current
, it won't work the right way because the original ref object will be lost. And the relevant React component expects that the object is preserved and is mutated by whatever sets the ref.
To overcome this, I manually convert text-input
properties from JS to CLJS but in a shallow way (`js->clj` is deep).
And that works because Reagent doesn't try to convert JS props when it wants JS objects and CLJS props when it wants CLJS objects.
Ah, interesting. Thanks! I'll try that.
Not sure though how a different kind of conversion can help if the problem is that an object is lost.
Unless the conversion is lossy at some point.
Consider this:
(-> #js {:ref #js {:current 1}} js->clj clj->js)
The resulting object will have the same information but it will be a different object in memory - any mutation to the original object will not be visible to the new one.
Now consider this:
;; Assuming shallow-js->clj exists somewhere.
(-> #js {:ref #js {:current 1}} shallow-js->clj clj->js)
In this case, the inner object will be preserved - any mutation to the original object will be reflected in the new one.Aha, I see. Thanks again!
Do you happen to have the code ready for shallow-js->clj
, by any chance?
Yep:
(defn shallow-js->clj-props [props]
(into {}
(map (fn [k]
[(keyword k) (oget+ props k)]))
(js-keys props)))
oget+
is from the cljs-oops
library. Should be the same as goog.object/set
, so you don't have to start using that library just because of this snippet.Cool. Thanks!
Nice library. I guess I'll use it, seeing as I don't currently use goog.object, either.
The thing is, goog.object
is built-in because it comes with Google Closure library that CLJS uses.
Ah, right.
Ok, that didn't help, because the original js-params
passed to render-input
already have ref.current
set to null.
Do I need to copy it from InputProps.ref
?
No, those are different refs. If you can create a repo with a minimal reproducible example, I could take a look and tell you what's wrong.
Ok