A minimalistic ClojureScript interface to React.js

it can be the same as your react method

athomasoriginal 2020-06-11T03:16:21.105Z

Whatever you do in React can carry over to Reagent, and CLJS in general.

athomasoriginal 2020-06-11T03:17:19.105200Z

Having said this, I often try to align to a CLJS approach. For example, in React its often 1 component per file. I’m not sure where this comes from, but it’s an odd convention IMO when you see how a clojure code base is structured.


might have come from java and c# where each class is a file. They used to do this less when react was just functions iirc

athomasoriginal 2020-06-11T03:19:02.106600Z

As for structures that work, I often do 1 file per screen

 ui.cljs (dumb components)

athomasoriginal 2020-06-11T03:19:29.106800Z

When the screens/components become more complex, I might break them up, but I often keep things as simple as possible.

athomasoriginal 2020-06-11T03:20:28.108300Z

@danieltanfh95 True.


for me i just follow the module method where each screen is a folder, and my components are in those folders, glued together with an index.cljs file


shared components are placed in a shared folder

athomasoriginal 2020-06-11T03:21:37.109700Z

It’s funny to me because when you read the React code base they opt for a CLJ style - 1 feature per file and their files are very large. There was an article they wrote on this once about why they moved to this approach.

coetry 2020-06-11T03:32:05.110Z

This thread helps a lot, thank you guys! I'll play around and get a feel for what makes sense 🙏

rap1ds 2020-06-11T06:56:53.110400Z

@y.khmelevskii What I like about Garden that it let's you write CSS as pure data. I can see that in emotion-cljs you can also pass Clojure maps with keywords and all, but Garden takes this a step further by providing selectors, units, etc. as data. So in practice, I was thinking that instead of this (example from README):

(defstyled Button :button
  {:color :red
   :font-size "14px"
   :padding "20px 40px"
   :&:hover {:color :blue}}) could write this:
(defstyled Button :button
  ;; Garden ->
  {:color :red
   :font-size (px 14)
   :padding [[(px 20) (px 40)]]}
  :&:hover {:color :blue})
The CSS as data is nice idea, but I'm not sure how important it is in practice. And anyhow, I'm not sure if it makes sense to use it in styled component context, but this was just something I had in my mind 🙂

y.khmelevskii 2020-06-11T07:04:27.110800Z

@rap1ds ahh, I understand you, Thanks for explanation. But I’m not sure that It’s a good idea to create a lot of functions to write css as data because we need to handle a lot of cases, like transform , transition , etc. And then we need to support all of them. I prefer to use string in case where it’s needed and I can’t see any problems here. Especially for me this cade

:font-size (px 14)
   :padding [[(px 20) (px 40)]]}
is not better than this 🙂
:font-size 14
   :padding "20px 40px"


Is it possible to use react-transition-group directly, or do we need to use this stuff via React.addons.CSSTransitionGroup ?


To answer my own question, yes, it is possible. You just have to adapt to the newer API.

Rebecca Bruehlman 2020-06-11T18:50:57.116Z

I have the following bit of code to create a datepicker:

(ns ui.components.picker.core
  (:require ["@material-ui/pickers" :refer [TimePicker DatePicker MuiPickersUtilsProvider]]
            ["@date-io/moment" :as MomentUtils]
            [ui.utils.core :as utils]
            [reagent.core :as reagent]))

(def component-styles {})
(def component-props {:inputVariant "outlined" :fullWidth true})

(defn date-picker-real [props & children]
  (let [all-props (-> component-props (merge props))]
    (utils/->component DatePicker all-props
                       :styles component-styles
                       :children children)))

;; Call this datepicker from the UI; really it's just wrapping the actual DatePicker component with the MuiPickersUtilsProvider, which is necessary to get this all to work.
(defn date-picker [props & children]
  [:> MuiPickersUtilsProvider {:utils (reagent/as-element MomentUtils)} [date-picker-real props children]])
However, after compiling this to a npm module, I get error messages like the following:
VM53713 react_devtools_backend.js:6 Warning: Failed prop type: Invalid prop `utils` of type `object` supplied to `MuiPickersUtilsProvider`, expected `function`.
    [. . .]
Uncaught TypeError: Utils is not a constructor
    at eval (useUtils-cfb96ac9.js?2ccd:11)
    at mountMemo (react-dom.development.js?61bb:15442)
    at Object.useMemo (react-dom.development.js?61bb:15738)
    at useMemo (react.development.js?72d0:1521)
    at MuiPickersUtilsProvider (useUtils-cfb96ac9.js?2ccd:10)
    at renderWithHooks (react-dom.development.js?61bb:14803)
    at mountIndeterminateComponent (react-dom.development.js?61bb:17482)
    at beginWork (react-dom.development.js?61bb:18596)
    at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
Is there some other way I'm supposed to pass in this MomentUtils object? I think the equivalent JS would be something like:
<MuiPickersUtilsProvider utils={MomentUtils}>
It's worth noting that this works just fine if I compile as a browser target, but it doesn't if I compile as an npm module...

p-himik 2020-06-11T18:57:53.116100Z

Try replacing :utils (reagent with :utils #(reagent.

valtteri 2020-06-11T18:58:20.116300Z

The easy way would be to use reagent input component instead of the normal input component. Then reagent’s caret-position-fix thing would be applied. Sadly in your use-case (react-mentions) the library doesn’t allow overriding the input component. So you’d have to fork / hack it.

p-himik 2020-06-11T18:58:39.116500Z

Oh, wait. If you can just pass MomentUtils in JS, then just do the same thing in Reagnet - just pass MomentUtils as is, without wrapping it.

p-himik 2020-06-11T19:00:18.116800Z

It's not the best way IMO. And with what I have described above, you don't have to fork/hack anything. Not the best because generally you can't rely on the way some library creates its internal component now since it may change later for some reason. That's why I don't really like the Reagent example of working with Material UI text input.

Rebecca Bruehlman 2020-06-11T19:22:48.117Z

Hmm, neither work. The latter gives me the same error, and the former gives me Uncaught TypeError: is not a function.

Rebecca Bruehlman 2020-06-11T19:23:03.117200Z

Really bizarre this works compiled under a browser target ... maybe it's a shadowcljs issue