reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
kennytilton 2020-09-18T00:49:51.005300Z

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.

kennytilton 2020-09-18T11:16:31.006400Z

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? 🙂

Lucy Wang 2020-09-18T05:51:21.005900Z

Or using refs + useEffect hook if you're using reagent 1.0 and functional components

kennytilton 2020-09-18T11:16:31.006400Z

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? 🙂

Leonid Korogodski 2020-09-18T14:33:52.006800Z

Hey, everyone. I'm new here.

2👋
Leonid Korogodski 2020-09-18T15:04:01.007500Z

Is this the right place to ask questions about specific problems we encounter when working with Reagent?

p-himik 2020-09-18T15:08:37.008Z

It sure is. Unless you're certain you're hitting a bug - then I'd just go straight to GitHub issues.

Leonid Korogodski 2020-09-18T15:10:35.008500Z

No, I'm not certain. Still relatively new to Clojure.

Leonid Korogodski 2020-09-18T15:11:41.009500Z

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

p-himik 2020-09-18T15:16:55.012300Z

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.

p-himik 2020-09-18T15:18:42.013Z

To overcome this, I manually convert text-input properties from JS to CLJS but in a shallow way (`js->clj` is deep).

p-himik 2020-09-18T15:19:17.013600Z

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.

Leonid Korogodski 2020-09-18T15:21:57.013900Z

Ah, interesting. Thanks! I'll try that.

Leonid Korogodski 2020-09-18T15:22:53.014500Z

Not sure though how a different kind of conversion can help if the problem is that an object is lost.

Leonid Korogodski 2020-09-18T15:23:40.015Z

Unless the conversion is lossy at some point.

p-himik 2020-09-18T15:26:34.018Z

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.

Leonid Korogodski 2020-09-18T15:29:47.018300Z

Aha, I see. Thanks again!

Leonid Korogodski 2020-09-18T15:49:11.018900Z

Do you happen to have the code ready for shallow-js->clj , by any chance?

p-himik 2020-09-18T15:52:31.020300Z

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.

1🙌
Leonid Korogodski 2020-09-18T15:52:58.020500Z

Cool. Thanks!

Leonid Korogodski 2020-09-18T15:57:03.021200Z

Nice library. I guess I'll use it, seeing as I don't currently use goog.object, either.

p-himik 2020-09-18T15:58:34.021600Z

The thing is, goog.object is built-in because it comes with Google Closure library that CLJS uses.

Leonid Korogodski 2020-09-18T16:10:57.021800Z

Ah, right.

Leonid Korogodski 2020-09-18T16:19:05.022800Z

Ok, that didn't help, because the original js-params passed to render-input already have ref.current set to null.

Leonid Korogodski 2020-09-18T16:22:37.023300Z

Do I need to copy it from InputProps.ref?

p-himik 2020-09-18T16:30:48.024100Z

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.

Leonid Korogodski 2020-09-18T16:35:14.024300Z

Ok