Fork me on GitHub
#reagent
<
2018-03-02
>
justinlee00:03:59

but most people probably use re-frame on top of reagent

exit200:03:50

@lee.justin.m so are you generally just dealing w/ component local state then and using specter to help manipulate the data?

justinlee00:03:02

If state is truly not shared between components, then I use local state (one exception is that sometimes I use a container/view pattern, but I consider those “one component” in a sense).

justinlee00:03:35

Otherwise, everything is in a single ratom. All mutations are done through functions that use specter and are always synchronous. Anything that involves the server is in a different file, and calls the state mutators as needed (e.g. setting a “loading” flag, setting progress updates, then adding the data and clearing the flag). It seems to work pretty well for me.

justinlee00:03:08

My project is small so code reuse among a big team of devs just isn’t a big priority for me.

justinlee00:03:49

reframe docs are thorough. this is a nice doc to get why frameworks might be good for you. https://github.com/Day8/re-frame/blob/master/docs/FAQs/DoINeedReFrame.md

johanatan01:03:41

@lee.justin.m i too am very much in the "build my own architecture camp" (from that document). I found re-frame to be too heavy on the boilerplate (but it is refreshing to see a motivation document that honest about whether the library it's describing is actually required)

wqhhust03:03:31

Any good lib to use modal window? I found reagent-modals, but is the mostly used? or any better option?

wqhhust03:03:52

or should use modal-panel in re-com?

fabrao16:03:37

hello all, is there any way to create atom dynamic?

justinlee16:03:38

@fabrao what do you mean by dynamic?

fabrao16:03:51

I give a list of html fields and generate atom for each one

justinlee16:03:46

i mean yea you can just map over your data and return (reagent/atom xxx)

fabrao16:03:30

oh, you mean (reduce #(conj %1 (%2 (reagent/atom "") ) [] [:field-1 :field-2]) ?

justinlee16:03:19

generally yes, but I don’t understand what you are trying to do at all. are you trying to pass a new atom to :field-1?

fabrao16:03:07

:field-1 is for using with [:input {:value @(:field-1 atom-store)}]

fabrao16:03:19

but I will pass it as dynamic fields to make inputs dynamicaly

fabrao16:03:23

so :field-1 will be from (for [field fields] (make-field field))

justinlee17:03:25

@fabrao I’m stilll not 100% following you, but I suspect what you really want is to use a cursor. https://github.com/reagent-project/reagent-cookbook/tree/master/basics/cursors

fabrao17:03:56

thanks for your help

justinlee17:03:11

if you want to create a bunch of input elements dynamically, you probably want to store the user’s input from those inputs in a single atom that is either global, or lives local to the parent component. you can just pass a reagent cursor as a parameter to each input. the input can treat the cursor as a normal atom and then the component’s atom will be automatically updated

lilactown18:03:06

did anyone watch Dan Abramov’s video on “suspense” in React 16?

lilactown18:03:14

I’m wondering how reagent is going to adopt & integrate with it

mikerod18:03:21

This is the first I’ve seen that… I wonder if that is really a nice solution to the problem described…

lilactown19:03:00

it seems like it 😅

worlds-endless20:03:58

What solutions have folks chosen for pop;-overs? I wanted to use goog.ui.Tooltip but am having rendering-order problems trying to attach it to things that don't exist yet

mikerod20:03:37

Throwing around promises.

mikerod20:03:31

I’m still wading through details of this stuff.

mikerod20:03:35

https://dev.to/swyx/a-walkthrough-of-that-react-suspense-demo--4j6a is something I was recently looking at, but not exclusively this

mikerod20:03:02

Loading data async’ly is done via throwing a promise etc

worlds-endless20:03:44

Ah! Got it! Use the :ref key on the element to get something approximately an onload of the element

crinklywrappr22:03:20

I have this code: (map-indexed (fn [i d] [:> t-row {:key (str "row-" i) :onClick #(js/alert (:name d))} [:> t-cell {:key (str "name-" i)} (:name d)] [:> t-cell {:key (str "age-" i)} (:age d)] [:> t-cell {:key (str "gender-" i)} (:gender d)]]) (:page-data @table-state)) generating this error: Warning: Every element in a seq should have a unique :key

crinklywrappr22:03:46

not sure what's missing - haven't i added a unique key to each element in the seq?

crinklywrappr22:03:44

Don't see what's missing when looking at the output (from the warning msg) either: https://pastebin.com/pbWTRdzn

justinlee22:03:05

@doubleagent do you have react dev tools installed in chrome? you can inspect the keys using that tool to see if that syntax is actually working

justinlee22:03:22

i would have thought that would have worked, but there’s something i don’t quite get with the way reagent does keys — the way you are doing it works with native html elements, but if you try to do that with a normal reagent component it doesn’t work and you have to use with-meta instead. i wonder if that’s true here too

justinlee22:03:34

but at any rate, react dev tools will tell you what’s going on

crinklywrappr22:03:20

Thanks. I'm still learning and not always sure where to look. Looks like semantic-ui is adding an element and not giving it a key

crinklywrappr22:03:32

also the td tag isn't getting a key

justinlee22:03:55

so try

^{:key (str "row-i")} [:> t-row ...
instead

crinklywrappr22:03:47

@justinlee doesn't appear to work

justinlee22:03:05

what happens?

justinlee22:03:40

i should point out that you need to do it for every element of course because i’m not sure where the key warning is coming from

crinklywrappr22:03:03

i get the same warning

crinklywrappr22:03:58

except when i tag as meta I don't see :key in the warning message output

justinlee22:03:19

wait what warning are you getting?

justinlee22:03:56

actually i must say that added tr shouldn’t be causing a warning anyway

justinlee22:03:03

it looks like you have keys in the right places

justinlee22:03:56

the key warning only applies when there series of sibling elements with the same tag

justinlee22:03:10

i’m not super comfy with the meta syntax. do you want to try again with with-meta.

justinlee22:03:23

i may have messed up the ^ thing

justinlee22:03:10

btw, if i’m reading the message right i interpret that to say that the warning is happening at the row level, not the cell level

justinlee23:03:31

also that may not be an error for the keys to have disappeared. i doubt it prints metadata.

crinklywrappr23:03:53

you're probably right about that

gadfly36123:03:43

@doubleagent please try this:

(for [[i d] (map-indexed vector (:page-data @table-state))]
  ^{:key (str "row-" i)}
  [:> t-row {:onClick #(js/alert (:name d))}
   [:> t-cell (:name d)]
   [:> t-cell(:age d)]
   [:> t-cell (:gender d)]])

crinklywrappr23:03:24

Thanks I'll give them both a shot

justinlee23:03:44

oh yea i thought that’s what you had tried before

justinlee23:03:13

oh there was a typy in my version

justinlee23:03:25

i had the “i” inside the string

justinlee23:03:42

how ironic that i typoed typo

crinklywrappr23:03:08

@justinlee no worries 🙂

justinlee23:03:25

well if you copied my version it wouldn’t work because the keys wouldn’t be unique

crinklywrappr23:03:44

I just used the ^ shorthand for metadata

crinklywrappr23:03:22

didn't copy verbatim

gadfly36123:03:12

huh, im surprised that didn't work then

crinklywrappr23:03:45

@gadfly361 thanks your idea worked

crinklywrappr23:03:06

This is what I have now: (map-indexed (fn [i d] ^{:key (str "row-" i)} [:> t-row {:onClick #(js/alert (:name d))} [:> t-cell {:key (str "name-" i)} (:name d)] [:> t-cell {:key (str "age-" i)} (:age d)] [:> t-cell {:key (str "gender-" i)} (:gender d)]]) (:page-data @table-state))

gadfly36123:03:13

Ok awesome, so looks like what @lee.justin.m was recommending does work then (sans the typo)

crinklywrappr23:03:23

actually don't need the :key on each t-cell either

crinklywrappr23:03:33

which you also suggested

justinlee23:03:04

if you want you could just do ^{:key i} — it only needs to be unique within that specific sequence

crinklywrappr23:03:20

yeah good point

gadfly36123:03:48

as an aside, the only gotcha i should note about using indexes for keys is if your data gets swapped out entirely ... itll think stuff survives that isn't actually the same stuff

justinlee23:03:08

one piece of magic I do not understand is how reagent/react knows when I’ve typed out 3 components in a row vs. mapping over some data to create 3 components in a row

justinlee23:03:36

@gadfly361 i’m not 100% sure, but I don’t think that’s true if the props change

justinlee23:03:24

hm maybe you are right.

gadfly36123:03:31

I think if your data is ["A" "B" "C"] and you switch it to ["A" "E" "C"] by swapping the ratom table-state, you may run in to an issue ... i dont think any props are involved there

justinlee23:03:08

if you mutate the ratom, the parent component will generate a new set of child components, which presumably will take “A” or “B” or whatever as a prop. somehow the data has to get to the child. i am almost positive that if you render a list with the same keys but where, say the second thing has new props, the child will get updated.

justinlee23:03:19

that suggests that you are right and you need to be careful. i always thought it was just a perf thing

gadfly36123:03:36

in any event, just be mindful of using indexes as they are not actually guaranteed to be unique if your dataset changes

gadfly36123:03:22

@lee.justin.m oh cool, hadn't actually seen that reference before that calls out indexes explicitly

justinlee23:03:08

if you mutate the ratom, the parent component will generate a new set of child components, which presumably will take “A” or “B” or whatever as a prop. somehow the data has to get to the child. i am almost positive that if you render a list with the same keys but where, say the second thing has new props, the child will get updated.

justinlee23:03:15

that document says that you can possibly get into issues with input elements, but it sounds relatively obscure. i believe if you just render non-input elements it’ll always work, although it may be inefficient if you reorder

justinlee23:03:30

I still don’t get why doubleagent doesn’t need keys on the t-cell components

gadfly36123:03:43

i think i've had issues with like react-flip-move and other visualization kind of things

gadfly36123:03:35

@lee.justin.m I think why you don't need keys on the t-cell is because of the granularity of the resulting seq

(map-indexed
 (fn [i d]
   ^{:key (str "row-" i)}
   [:> t-row {:onClick #(js/alert (:name d))}
    [:> t-cell (:name d)]
    [:> t-cell (:age d)]
    [:> t-cell (:gender d)]])
 [{:name   "Foo"
   :age    20
   :gender "male"}
  {:name   "Bar"
   :age    32
   :gender "female"}])
;; Which would effectively turn in to:
;;    (
;;      [:> t-row {:onClick #(js/alert "Foo")} [:> t-cell "Foo"] [:> t-cell 20] [:> t-cell "male"]]
;;      [:> t-row {:onClick #(js/alert "Bar")} [:> t-cell "Bar"] [:> t-cell 32] [:> t-cell "female"]]
;;      )
This just produces a seq of two elements, so you only need keys at the top-level to be able to identify each

justinlee23:03:33

@gadfly361 try this out. the first table will not generate an error. i.e. if you comment out the second table you get no errors.

(def data
  [{:name   "Foo"
    :age    20
    :gender "male"}
   {:name   "Bar"
    :age    32
    :gender "female"}])
(defn test-component
  []
  [:div
   [:table>tbody
    (map-indexed
     (fn [i d]
       ^{:key (str "row-" i)}
       [:tr {:onClick #(js/alert (:name d))}
        [:td (:name d)]
        [:td (:age d)]
        [:td (:gender d)]])
     data)]
   [:table>tbody
    (map-indexed
     (fn [i d]
       ^{:key (str "row-" i)}
       [:tr
        (map (fn [d] [:td d]) (vals d))])
     data)]])