Fork me on GitHub
#reagent
<
2018-09-22
>
justinlee18:09:10

@hkjels you can use fragments or you can just use reduce instead of map to create a single vector

parrot 4
athomasoriginal23:09:50

What is going on here?

(defn my-comp
  [{:keys [class] :as props} & children]
  (into [:div {:class ["class-one" class]}] children))

; works
[my-comp {} [:div ] [:div ]]

; does not work
[my-comp [:div ] [:div ]]
By “does not work” I mean that I would expect the second to also render the :divs but it does not…

justinlee23:09:21

@tkjone in the second version you are passing the first div as the props

athomasoriginal23:09:26

For some reason I was thinking that reagent was expecting the first to always be a map (and this would become props) and if not a map everything else would become children

justinlee23:09:16

I wish that were the case. The only thing it does that is special with a props map is that it will put a props map on the actual props property and the remainder of the arguments on props.children

athomasoriginal23:09:06

How would I go about defining my-comp so I could pass it a map, or not, and behave as I expect?

justinlee23:09:51

you could check the type of the props object. if it is a vector then treat it as a child

athomasoriginal23:09:33

haha that was what I wanted to do, but for some reason I have not seen this pattern in any example code I reviewed.

athomasoriginal23:09:00

I figured this would be pretty common

justinlee23:09:12

for some reason reagent code doesn’t often do the “arbitrary children” pattern

justinlee23:09:33

the whole technique of treating ordered arguments as children is weird

athomasoriginal23:09:40

The common case I can think of is when creating a component library:

(defn para 
  [props & children]
  (into [:p props] children))
In the above example, component libraries will often make it so that the component has sane defaults which would mean that for most case you just need to call
[para "This is a paragraph"]

athomasoriginal23:09:24

and then overwriting defaults is allowed by providing a map as the first arg

athomasoriginal23:09:09

is the accepted way in reagent to do

(defn para 
  [props & children]
  (if ( = props map)
     ;; stuff 1
     ;; stuff 2

justinlee23:09:09

a runtime type check will work reliably. just use (if (not (map? props)) ... ...)

justinlee23:09:30

yea that’s probably the best you can do with reagent

athomasoriginal23:09:05

Good to know. Yeah, I was working on this and was blown away that after several months of solid reagent I had not come across this. I also read through this (quickly, I admit) https://github.com/reagent-project/reagent/issues/13 and it had me thinking that reagent built in a solution