nosco / hx

A simple, easy to use library for React development in ClojureScript.
MIT License
247 stars 16 forks source link

Keys syntax suggestion #7

Closed akond closed 5 years ago

akond commented 5 years ago

It would have been easier if we had (hx/defnc HasChildren [children] instead of (hx/defnc HasChildren [{:keys [children]}]

lilactown commented 5 years ago

Do you mean specifically for children? Or all props?

lilactown commented 5 years ago

I'm of the opinion that props should always be modeled as a map (same as React proper). I think that having named keys scales way better to larger amounts of props, and it also makes threading props way easier.

I have thought about spreading children into the function call as it feels more Clojure-y

(hx/defnc HasChildren [props & children]
akond commented 5 years ago

I mean I don't want to access properties like (:some props) or (:children props) all the time. This is a lot of redundant typing. Children is just another prop to me. What I mean is to have something like this:

(defmacro defc [name args]
    `(defn ~name [{:keys [~@args]}]))

so that I could do

(defc x [a b c :as vv]) or (defc x [a b c])

pepe commented 5 years ago

Well I actually like to access properties through keys. With destructuring it is not that big effort and it stays very Reacty.

Just my two cents tho.

lilactown commented 5 years ago

Yeah. The biggest downside is that your first example, (defc x [a b c :as vv]), doesn't work. The :as vv needs to be outside of the vector where you enumerate your keys. So if want to thread your props, it becomes very troublesome. Here's an example when you'd want that:

(hx/defnc ThemedButton [{:keys [children] :as props}]
  (let [theme (:button-style (useContext theme-context))]
    (into [:button (update props :style merge theme)] children))

Without treating props as a map (and destructuring), you'd have to enumerate every single prop you want to accept, which just isn't tenable. At the moment, I think that having to type {:keys [ ... ]} is a small price to pay.

I also think that it may help people who are coming from reagent with the shift in semantics in their hiccup, since reagent allows you to pass in props as un named parameters, whereas React (and by extension hx) requires you to pass them all in as a map with keys. Signatures of components created by defnc match the way you would use them in hiccup (except for those pesky children!).