it can be the same as your react method
Whatever you do in React can carry over to Reagent, and CLJS in general.
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
As for structures that work, I often do 1 file per screen
app/
auth.cljs
settings.cljs
feature.cljs
ui.cljs (dumb components)
app.cljs
When the screens/components become more complex, I might break them up, but I often keep things as simple as possible.
@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
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.
This thread helps a lot, thank you guys! I'll play around and get a feel for what makes sense 🙏
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.
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...Try replacing :utils (reagent
with :utils #(reagent
.
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.
Hmm, neither work. The latter gives me the same error, and the former gives me Uncaught TypeError: utils.date is not a function
.
Really bizarre this works compiled under a browser target ... maybe it's a shadowcljs issue