-
Notifications
You must be signed in to change notification settings - Fork 414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reusable components following HTML semantics of Opional Attributes and Variadic Children #596
Comments
1.4 is what I'm using:
Adding a macro to define components would allow solving other big problems of Reagent, but I don't know if that is going to happen. UIx2 and Helix handle this nice. They just enforce React way of component fns just taking the props object as parameter, nothing else. They also allow placing children into the elements directly, without |
Thanks for sharing Juho! Very happy to hear I'm not alone with this pattern. 🙂
Can you share what other issues might be addressed?
Thanks for pointing this out, it seems like UIx2 and Helix are not using Hiccup and BOTH use a macro for reusable components! (defmacro defcomp
[name props & body]
`(def ~name (fn [& args#]
(let [~props (if (map? (first args#))
(assoc args# :children (seq (drop 1 args#)))
{:children (seq args#)})]
~@body))))
(defcomp button [{:keys [children on-click]}]
(into [:button {:on-click on-click}] children)) As of |
I'm preparing a blog post which would touch on this and other problems with Reagent. Your macro example performance isn't going to be the best:
So because Reagent is doing work to support Hiccup, you need to do extra work to transform data back to format that is closer to the original. Unfortunately there is no way to fix this in Reagent. You can check UIx presentation by Roman for screenshot of UIx vs Reagent performance profile, Reagent call stack is 5x deeper: https://www.youtube.com/watch?v=4vgrLHsD0-I |
Hello friends, thanks for maintaining Reagent! 🙌
Through the last 11 months of coding Clojure, I've been writing quite a lot of Reagent code and it's mostly been a pleasant journey thanks to your effors.
I might be missing something(still quite new to Clojure), it's been a bit hard for me to achieve the familiar HTML semantics of Opional Attributes and Variadic Children.
1. Possible solutions to reusable components
I've been looking over possible designs I've seen in the internet considering their pros and cons.
1.1 Positional Attrs and Positional Children
✅ simplest API
❌ requires
[:<>]
wrapper forchildren
❌ doesn't follow Hiccup/HTML semantics
❌ introduces breaking changes
1.2 Required Attrs and Variadic Children
✅ simple API
✅ variadic children
❌ requires positional
attrs
, so it doesn't follow the semantics of HTML tags1.3 Optional Attrs and Optional Children
✅ harder to introduce a breaking change
❌ requires
[:<>]
wrapper forchildren
❌ doesn't follow Hiccup/HTML semantics
1.4 Optional Attrs and Variadic Children
✅ follows Hiccup/HTML semantics
✅ harder to introduce a breaking change
❌ requires boilerplate
❌ hides the "real" arguments inside
let
binding2. Proposal
It could be that a better solution already exists, but I've missed it, but if not...
Here is the distillation of what could bring HTML semantics to reusable components in Hiccup and Reagent.
2.1 Optional Attrs and Variadic Children with a
defcomp
macro 😎 👍This macro enables the standard HTML semantics in re-usable Reagent components without extra boilerplate and trade-offs of solutions 1-3.
✅ follows Hiccup/HTML semantics
✅ reduces the risk of introducing a breaking change
✅ no boilerplate
✅ arguments easily readable in
defcomp
args❌ relies on a macro
Example of usage:
Please share your thoughts on this, I would really appreciate any feedback!
The text was updated successfully, but these errors were encountered: