wrote up some thoughts on “Why Helix”: https://github.com/Lokeh/helix/blob/master/docs/motivation.md also some FAQs, like “What about hx?” and “What about hiccup?“: https://github.com/Lokeh/helix/blob/master/docs/faq.md the “What about hiccup?” FAQ goes into some of the the tradeoffs that hiccup parsing has and also explains some of the motivations to move away from Reagent’s all-state-belongs-in-a-reactive-atom
The link to ‘creating a custom macro’ at the bottom of the FAQ has an extra /docs/ in it.
Thanks!
currently setting up a project that uses both helix and fulcro 🙂
nice! what's the use-case for using helix and fulcro together?
(I don't know much about fulcro, other than I know it has ways of creating components and elements)
i'd rather use react hooks for handling component local state i find it easier to keep state in sync that way (rather than messing with componentDidMount and componentDidUpdate hooks)
still learning fulcro but looks like it encourages making most state global, which I dislike, so definitely want to have full power of react hooks at my disposal
https://twitter.com/brian_d_vaughn/status/1228150318069714944
Hi @lilactown! It would be great to add support react defaultProps
.
Currently I should do something like this
(defnc <Button>
[props]
(d/button props))
(set! (.-defaultProps <Button>) #js {:type :submit})
I’m not sure about best interface but I can see 2 ways to manage it:
1.
(defnc <Button>
[props]
{:default {:type :submit}}
(d/button props))
2.
(defnc <Button>
[props]
(d/button props))
(defdefp <Button>
{:type :submit})
Does it make sense?
If yes, I think I will be able to implement it and push PR@y.khmelevskii you can specify defaults in two ways (depending on what you need):
(defnc Button
[{:keys [type] :or {type :submit}}]
;; use `type` inside the body. if it's not passed it will default to `:submit`
...)
or, if you need to pass it to a child with a default:
(defnc Button
[props]
(d/button {& (merge {:type :submit} props)}))
both of these just use native ClojureScript features and have nothing to do with React defaultProps, which IMO are an anti-pattern and might be deprecated. See https://github.com/reactjs/rfcs/pull/107
hmm, it’s surprising for me to know that default props could be deprecated. In my case both of your examples doesn’t work. But anyway I will think about another approach, thank you
what do you mean they don’t work? how do they not work?
if they do not work, there’s a bug in helix and I should fix it. please let me know more information
my case a little bit difficult then I described above. I’m trying to describe correctly my case
so, I created a tiny wrapper for emotion (styled components) js lib https://emotion.sh/docs/styled If removing all macros and create styled component using interop I have something like this:
["@emotion/styled" :as styled]
...
(defnc button
[props]
(d/button {& props}))
;; (set! (.-defaultProps button) #js {:kind :primary})
(def <Button>
((.default styled button)
(clj->js
[{:color :red}
#(when (= (-> % js->clj (get "kind"))
:primary)
(clj->js {:color :green}))])))
I need to apply color: green
if :kind
prop is :primary
. By default this prop should be :primary
.
So, this example works only when I uncomment set!
line.
Of course with a few macros syntax looks much better(def <Button>
(-> #js [#js {:color :red}
(fn [props]
(let [{:keys [type] :or {type :primary}} (cljs-bean.core/bean props)]
(when (= :primary type)
#js {:color "green"})))]
((.default styled button)))
yes, I understand :) you moved defaults to styled component. But it’s not a convenient because I need to check type
props in many css rules and in your approach I always should define default value:
(def <Button>
(-> #js [#js {:color :red}
;; type
(fn [props]
(let [{:keys [type] :or {type :primary}} (cljs-bean.core/bean props)]
(when (= :primary type)
#js {:color "green"})))
;; disable?
(fn [props]
(let [{:keys [disable? type] :or {type :primary}} (cljs-bean.core/bean props)]
(when (and disable? (= :primary type))
#js {:color "gray"})))]
((.default styled button)))
of course it’s artificial exampleThere is more realistic example
(defcss-when --primary [{:keys [kind]}]
(= kind :primary)
{:color :green})
(defcss-when --disable? [{:keys [disable? kind]}]
(and disable? (= kind :primary))
{:color :gray})
(defstyled <Button> button
{:border-radius 8
:padding "12px 32px"
:border :none
:text-align :center
:cursor :pointer}
--primary
--disabled?)
in your case I should do
(defcss-when --primary [{:keys [kind] :or {kind :primary}}]
and
(defcss-when --disable? [{:keys [disable? kind] :or {kind :primary}}]
but I want set default properties onceyeah in this case I guess you do want to set default props because styled components tries to be smart and read the .-defaultProps
property on the component you pass in
FWIW I do not like styled components. I vastly prefer just generating the classes and using them in a component:
(defcss --primary
{:color :green})
(defcss --disabled
{:color :gray})
(defcss default
{:border-radius 8
:padding "12px 32px"
:border :none
:text-align :center
:cursor :pointer})
(defnc Button
[{:keys [type disable?] :or {type :primary}]
(let [primary? (= :primary type)]
(d/button {:class (cx default
{primary? --primary}
{(and primary? disable?) --disabled})
& props))
cx
is a wrapper around emotion/cx
that’s pretty much verbatim how we write code at work
this way your styling isn’t coupled to the props shape of your component. so you don’t end up repeating yourself over and over