Fork me on GitHub
#reagent
<
2017-04-12
>
curlyfry08:04:10

I want to insert several cells into a table based on a condition. Is there a nicer way to do it than this?

[:tr
 [:td "Cell 1"]
 (when (pred x)
   (list ^{:key 1} [:td "Extra cell 1"]
         ^{:key 2} [:td "Extra cell 2"]))]

fernandohur09:04:22

Any reason why you consider this approach ‘bad’?

curlyfry10:04:23

Not really, I'm relatively happy with it. Was just wondering if anyone had found a nicer pattern.

fernandohur11:04:23

I looks very clean and readable if you asked me 🙂

pesterhazy10:04:20

@curlyfry that's pretty close to nice IMO

pesterhazy10:04:23

somewhat more explicit; (cond-> [:tr [:td "Cell 1"]] (pred x) (into [[:td {:key 2} "2"] [:td {:keys 3} "3]]))

mikethompson10:04:19

Or maybe

(-> [:tr [:td "1"]]
    (into  (when (pred x)  
             (list [:td "2"]  [:td "3"]))))
Note: how I don't have to use a :key (@pesterhazy could have omitted :key too)

pesterhazy10:04:19

@mikethompson, do you not need :key?

mikethompson10:04:47

No, :key only needed when you supply a list

mikethompson10:04:34

Your solution and mine use into to fold the :td into the vector, rather than supplying them as an embedded list

pesterhazy10:04:14

@mikethompson but doesn't React itself require keys for elements with multiple children? https://facebook.github.io/react/docs/lists-and-keys.html

mikethompson10:04:41

This works without :key

(defn view 
   []
   [:tr  
      [:td  "1"]  
      [:td "2"]
      [:td  "3"]])

pesterhazy10:04:58

I just tried it, you're right,but I'm not sure why

pesterhazy10:04:12

according to React's documentation it should issue a warning, shouldn't it?

mikethompson10:04:38

This will produce a warning:

(defn view 
   []
   [:tr  
      [:td  "1"]  
      (list [:td "2"]
            [:td  "3"])])

mikethompson10:04:53

Notice the embedded list

pesterhazy10:04:56

but that's a separate issue, a warning generated by reagent

pesterhazy10:04:22

there are warning printed by React itself

pesterhazy10:04:50

there must be something I'm missing here...

juhoteperi11:04:49

@pesterhazy Reagent adds react keys to vectors automatically (it uses the index), but not lists

juhoteperi11:04:25

(I could be wrong, I haven't checked the code)

pesterhazy11:04:00

@juhoteperi very interesting. If reagent does that, it seems like a bad idea, given that react chooses not to assign keys automatically

juhoteperi11:04:05

@pesterhazy I guess I was wrong

juhoteperi11:04:41

In React <ul><li>foo</li><li>bar</li></ul> doesn't need keys, but const list = ["foo", "bar"].map((v) => <li>{v}</li>); return <ul>{list}</ul> does need keys

juhoteperi11:04:07

My understanding is that React can differentiate static lists and dynamic lists

juhoteperi11:04:31

In static list case, all the list elements have createElement call in the parent createElement

juhoteperi11:04:02

In dynamic list case, there is single Array (created by map)

pesterhazy14:04:01

@juhoteperi nice detective work

pesterhazy14:04:51

reagent spreads the arguments using apply in its call to createElement

pesterhazy14:04:47

so it calls createElement("div", null, li1, li2, li3) instead of createElement("div", null, [li1, l2, l3])

pesterhazy14:04:19

and only the latter form triggers the warning because it is assumed that the first version is "manual" or static

pesterhazy14:04:28

is that your theory?

pesterhazy14:04:07

React is full of these little inconsistencies (you can pass multiple scalars or an array) with subtle differences

joshkh15:04:07

baking-soda looks fantastic but i'm locked into bootstrap 3 (instead of 4). is there an equivalent? https://github.com/gadfly361/baking-soda

joshkh15:04:22

also, can someone explain what :component-function does in the context of Form 3 components? thanks! 🙂 https://github.com/reagent-project/reagent/blob/4ea070d15a50c5fcee8dee526b79db9e6c8dd6aa/test/reagenttest/testreagent.cljs#L415

joshkh15:04:35

that's literally the only reference in the project and it's in a test

gadfly36117:04:40

@joshkh would you be willing to use https://react-bootstrap.github.io/introduction.html? If so, I can probably wrap it for use with reagent

mikeb18:04:38

May I ask what does the ^{:key 1} does in this expression? ` (list ^{:key 1} [:td "Extra cell 1"] ^{:key 2} [:td "Extra cell 2"]) `

mccraigmccraig18:04:13

@mikeb it attaches a metadata map {:key 1} to the :td hiccup vector, which is then used by reagent to assign a component key to the generated react component https://facebook.github.io/react/docs/lists-and-keys.html

mikeb18:04:19

Interesting, and why do that rather than just [:td {:key 1} "Extra cell 1"] ?

mccraigmccraig18:04:35

it makes sense when the caller has the context to provide the key and rather than a literal [:td ...] vector you have another component fn call. i’m not sure if either form is preferred over the other

mikeb18:04:38

Ok, thanks!