Fork me on GitHub
#reagent
<
2019-09-26
>
timrichardt13:09:01

Is there a best practice to pass CSS and HTML attributes to reagent components? Currently, I am doing it like below to provide some overwritable defaults

(defn Component
  ""
  []
  (reagent/with-let
    [props    (reagent/props (reagent/current-component))
     children (reagent/children (reagent/current-component))]
    (into [:div
           {:style (merge {:background "red"}
                          (:style props))}]
          children)))

[Component {:style {:background "blue"}}]

lilactown16:09:51

@timrichardt there isn’t anything enforced, but I always try and have my component take in a props map as the first argument

lilactown16:09:02

the way you’re doing it here, though, is: 1. Incorrect - it will only ever get the props / children on the first render. it won’t react to new props because you are using with-let 2. more complicated then it needs to be

👍 4
lilactown16:09:20

here’s how I would do it:

(defn component
  [{:keys [style] :as props} & children]
  (into [:div {:style (merge {:background "red"} style)}]
        children))

lilactown16:09:52

used like [component {:style {:background "blue"}} "foo" [:button "bar"]]

timrichardt16:09:12

This is how I am doing it right now, I would like to have the ability to omit props and children without the hassle of the multi-arity definitions.

timrichardt16:09:20

Could be automated by a macro, but I prefer to have something more native.

timrichardt16:09:11

And I am not sure which variant results in less code/compile time.

lilactown17:09:20

you should be able to omit props just fine with that definition I gave

lilactown17:09:28

(or children)

lilactown17:09:44

I suppose the issue would be if you wanted to pass in children, but not props

lilactown17:09:04

you’d have to do [component nil "foo"]

lilactown17:09:45

ultimately this is a problem with how reagent treats arguments, as they are like an fn rather than a props collection like raw React

lilactown17:09:31

using a library that binds more closely to React, like hx, you can easily do what you’re talking about because the hiccup parser has to understand the difference between props and children at parse time

timrichardt17:09:33

Thanks for the hint.