if the component has propTypes set on it, you can access it via ClojureScript like:
(.-propTypes Button)
however, this is something that the author of the JS component elects to do. not everyone does it consistently
Hi, I am new to clojurescript and reagent, so this is a very noob question. How do I use spread operator to pass all props to a child component in reagent?
<Box {...props}>
Thanks.@chin321 You posted a nearly identical question in #re-frame just a few minutes ago. We generally discourage cross-posting of question and ask folks to just be a bit patient about getting a question answered when folks are around. Right now it's after midnight on the East Coast of the US so there's fewer folks here than during either Europe's day or America's day.
I have to say, I don't really understand your question... Can you provide an example in ClojureScript to illustrate what you're asking about?
@chin321 [:> Box props]
the spread operator is only needed in JS for copying the object
So :>
means "apply" basically?
if you have other options
[:> Box (merge {:open true} props)]
just merge the maps
@seancorfield no, its whats needed for interop with a react component
so if you have a react component, to wrap it into reagent one way to do it is to use [:>
Cool. I'm only just getting back into cljs after a seven year gap so this is useful for me.
I figured it is more suited to this channel, so I deleted the question from #re-frame. Thanks for letting me know.
I'm just getting back into it after ~4
but its just syntax sugar around adapt-react-class
if you have a reagent component
so a function that returns hiccup
Thanks :thumbsup::skin-tone-2:
its up to you to structure the signature of that function such that it will accept "passthrough" options
(defn box [open? color]
...)
https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md There are some other weird looking reagent hiccup forms like :f> and :<>
so in this case, you have to manually pull out what you want to pass
because it expects two "positional arguments"
[box true "red"]
[box (:open? props) (:color props)]
if you write it such that it accepts a map, you can just pass the map as is
(defn box [{:keys [open? color]}]
...)
[box {:open? (:open? props) :color (:color props)}]
[box props]
[box (merge {:color "red"} props)]
all react components take some "props object", so its more uniform there
Would you say it's "best practice" to write components to accept a single map argument? That seems to fit with more general Clojure(Script) recommendations when you otherwise would have arbitrary arguments...
It's fairly common, and most large react libraries utilizes the single map pattern
re-com from day8 is written with a sequence arg list. Looks pretty, but makes it a bit harder to programmatically build up props
After a couple of years of using the "re-com way", I've found that using just a single map is so much better. Even if you don't change the props - just passing them through some component is both easier and simpler.
When designing re-com (about five years ago, when I was young and foolish) my goodness we agonized over that decision endlessly: "single map arg" vs "named args" (map vs pseudo-map). One way (map arg) would have been like this:
[button {
:label "click me"
:on-click #(...)
:disabled? false}]
vs the alternative named args (pseudo map) approach:
[button
:label "click me"
:on-click #(...)
:disabled? false]
It was ultimately a trade-off between the ease of "prop-drilling" (single map) verses the reduced visual noise (of not needing {} because the args are a pseudo map).
At the time, we felt the amount of "prop-drilling" with re-com was relatively small (because these components are leaves), whereas there is a LOT of hierarchical data structures to create and avoiding needing paired {} is a blessing. So that ended up tipping us in the named args (pseudo map) direction.
That was our thought process. I still feel we did the right thing, on balance, without ever feeling 100% sure about it. But, as a general rule, you should absolutely favour a single map arg (for ease of prop drilling), unless you find compelling reasons not to.There are other (maybe minor) points to consider:
- Not every editor can level the values of named args (Cursive can not, for example)
- A map literal with an odd number of values will result in a compile time error, as opposed to a run time one
- With a map literal, you can embed children as it's done in the rest of the React world - by adding more elements to the Hiccup vector. This, in a way, removes the noise with :children
, :child
, :label
, and such (all from re-com)
All good points.
ooff. Our first commit to re-com was July 2014.
Time for re-com2
?
And should it use tailwinds :-)
Not using Bootstrap would be nice.
"Utility first" CSS was the term I was searching for (tailwinds is just the latest cool kid on that block?)
Anyway, the latest version of re-com allows you to style all the "parts" of a component.
Is the resulting css a static css file or compiled into the js bundle?
Should be out this week
Small step
For reusable components, tying it together with a CSS framework really makes it harder to use in different environments. Some React libs have solved this quite well with customizable in-JS-styles, like React-select https://react-select.com/styles
Indeed. On one of the projects, I've been working with Material-UI that uses a CSS-in-JS approach. It's quite pleasant.
Material-UI StyleProvider approach is probably definitely easier for larger component library type project. React-select requires providing the options every time component is used.
Another small thing to consider - using reagent.core/class-names
. It makes composing classes so much easier.
Also, I'm just a fan of using keywords for classes. :)