Fork me on GitHub
#reagent
<
2018-03-01
>
pesterhazy00:03:42

@pmooser hard to say without knowing specifics, but a couple of things to watch out for: https://presumably.de/reagent-mysteries-part-2-reloading.html

juhoteperi18:03:41

Do the new docs yet document React keys?

justinlee18:03:39

i wrote a little section on that but i’m not sure it made it in. https://gist.github.com/jmlsf/17c588deb326e538dcea6847bc66db9b#keys

justinlee18:03:55

I’ll submit a PR so that it gets added to the creating components doc

justinlee18:03:39

if you think that should be done differently or more thoroughly feel free to steal it and edit it

justinlee18:03:47

i think it mostly copied it from the release notes

gadfly36118:03:49

@lee.justin.m can you modify the examples to show them in the context of a seq like for

justinlee18:03:00

yea that’s a good idea

gadfly36118:03:02

That's why I had dropped it for the moment

justinlee18:03:14

that’s considerably more useful

juhoteperi18:03:26

Yeah, I'm thinking about writing why they are needed etc. and comparison between workarounds (and what they do and why they aren't as good as real unique keys)

juhoteperi18:03:31

Thiis is probably one of the most common things I mention during reviews and looks like this isn't documented yet

justinlee18:03:08

@juhoteperi if you want to take that on I would be very appreciative. feel free to use any or none of what i put together. it really needs to be written and probably be in its own section. we should probably put references to it in the sequences section and the creating components section too

justinlee18:03:46

hm never mind there isn’t a sequences section. we just mention it obliquely in the faq at one point

exit219:03:34

Hi all, I’m fairly new to reagent w/ previous knowledge of om.next. I’m trying to simply figure out how to pass route params into a component, but all attempts fail. Here’s the code, anyone have any ideas? https://gist.github.com/njj/cdc852e51e255e99b62946a13565a665#file-foo-cljs-L31

justinlee19:03:48

@njj i just stick the params in the router atom and then my top level component pulls from the atom and passes as a param

exit219:03:58

I see, so my (defonce page (atom #'home-page)) needs to pass arguments?

justinlee19:03:05

the sample code you pasted puts the actual component in the atom. i don’t do that. i put a keyword that represents the component and then in my top-level router component i just have a case statement

justinlee19:03:23

(secretary/defroute "/app/notebook/:notebook-id"
                    {notebook-id :notebook-id}
                    (reset! current-route {:page :notebook
                                           :notebook-id (str->int notebook-id)}))

justinlee19:03:04

then later I check for the value of :page and return a hiccup form with the right component and pass the parameters to that i grab from :notebook-id

exit219:03:23

any chance you can share a bit more?

justinlee19:03:31

i had to edit out a bunch of stuff, but I think this is right:

(defn router-component
  []
  (debug-fmt "routing to %" (:page @current-route))
  (case (:page @current-route)
    :notebook [home-component {:view :notebook :notebook-id (:notebook-id @current-route)}]
    ;; more cases here
    [:div "Page not found."]))

(defn mount-root []
  (reagent/render [router-component]
    (.getElementById js/document "app")))

exit219:03:04

what is current-route in this case?

exit219:03:12

is that the same as current-page on mine?

justinlee19:03:18

its your page atom

justinlee19:03:34

oh yea current-page

justinlee19:03:08

there’s not thing special about it. you just need a component at the top level which derefs some kind of router state and returns the right component

exit219:03:18

slight abstraction, I’m into it

justinlee19:03:20

how you structure the router state is totally up to you

justinlee19:03:43

i like things nice an explicit so i shy away from the techniques that use multimethods and weird stuff like that

exit220:03:26

@lee.justin.m does your current-route just look like:

exit220:03:29

defn current-page []
  [:div [@page]])

justinlee20:03:03

(defonce current-route (reagent/atom {:page :home}))

justinlee20:03:03

oh sorry i confused my self above. yea current-page is more similar to my router-component and page is similar to my current-route

justinlee20:03:12

i led you stray a bit there

justinlee20:03:06

the only difference is that instead of putting the component in the ratom and using it directly in current-page you would put data in the ratom and just return the hiccup based on that data

justinlee20:03:39

now that i’m thinking about it, you could actually avoid my case statement by just putting hiccup in the router ratom

justinlee20:03:03

like instead of

(reset! current-route {:page :notebook
                                           :notebook-id (str->int notebook-id)})
i should probably just do
(reset! current-route [notebook-component blah blah blah])
and then just have my router-component look like your current-page

justinlee20:03:50

i don’t know why i didn’t think about that before. i had run into the same problem you are having but my solution is a little clunky

exit220:03:43

hmm not sure if I follow haha

exit220:03:08

what did you router atom end up looking like then?

justinlee20:03:45

it would be easier (and more like what you are doing) if I just did this:

(defonce current-route (reagent/atom [home-component]))
(secretary/defroute "/app/notebook/:notebook-id"
                    {notebook-id :notebook-id}
                    (reset! current-route 
                            [home-component {:view :notebook 
                                             :notebook-id (str->int notebook-id)}]))
(defn router-component
  []
  @current-route)
I haven’t tested but that should work

exit220:03:30

I kind of got it working passing the params down

exit220:03:40

broke my back button somehow on the way though haha

exit220:03:40

oh its working magically 😄

exit220:03:24

things are still a little weird, but getting closer

justinlee20:03:48

i didn’t read it to carefully but yea that’s basically what I should be doing 🙂

exit220:03:05

the destructuring is a bit weird for the defroute

exit220:03:19

it seems to be passing the entry hash instead of just the value

justinlee20:03:29

oh that’s because you’re doing [step-page {:step-id step-id}] instead of [step-page step-id]

justinlee20:03:41

your component expects a value but you’re passing it a map

jmckitrick20:03:12

Supposed I’m using an imbedded component with ‘:>’ notation, and it has a ‘refs’ property with a name I pass in. Later on, I’ll need to access the component by that name to access its data. What’s the best way to do that?

mikethompson21:03:41

I had it down to do a refs.md using that material as a base, but would be very happy to see someone else do it

justinlee21:03:34

@jmckitrick i’m not quite sure what you are trying to do

jmckitrick21:03:26

Hmm. Let me poke around a bit more, @lee.justin.m

exit221:03:00

@lee.justin.m does your home component look for the :view and then switch on that?

exit221:03:20

also wtf is a Hiccup? 😄

justinlee21:03:42

haha. when you write [:div "hi"], that vector is called a hiccup

exit221:03:08

so hiccup is just that vector representation of a dom el

exit221:03:12

I ask because I’m trying to clean this up:

exit221:03:15

(defn router-component []
  @current-page)

(defn mount-root []
  (r/render [router-component] (.getElementById js/document "app")))

justinlee21:03:31

exactly. for me, realizing that all you are doing is writing functions that return plain clojurescript vectors (i.e. hiccup), was a major revelation in how reagent works. because i was pretty new to cljs, this kind of thing (defn hi [] [:div "hi"]) looked like magic syntax to me. but it isn’t. it’s just data and nothing will happen to it until you pass it to reagent

exit221:03:36

but when I try to just pass @current-page, reagent yells at me about hiccups

justinlee21:03:15

what’s it saying? @current-page should just be a vector

exit221:03:55

(defn mount-root []
  (r/render [@current-page] (.getElementById js/document "app")))

exit221:03:13

this doesn’t work

exit221:03:20

invalid arity

justinlee21:03:23

get rid of the [] around @current-page

justinlee21:03:39

you are effectively passing it [[:div "hi"]]

exit221:03:51

no errors but routing doesn’t seem to work

exit221:03:04

route changes but page doesn’t update

justinlee21:03:48

you need that wrapping component

justinlee21:03:09

you can’t do it directly because there’s nothing to react to the atom changes

justinlee21:03:48

so the router-component, which seems to do nothing, actually does do something: it reacts to the current-page mutations

exit221:03:11

its weird you cant even do #(@current-page)

justinlee21:03:51

again, even if you do that, r/render doesn’t know to re-render when current-page mutates

exit221:03:13

(defn mount-root []
  (r/render [(fn [] @current-page)] (.getElementById js/document "app")))

exit221:03:14

this works

juhoteperi21:03:04

#(@current-page) is same as #([a vector here]) i.e. it will try to call the vector as function

justinlee21:03:12

huh yea i guess reagent can make an anonymous function reactive

jmckitrick22:03:05

Supposed I’m using re-frame, and after an ajax request succeeds, I want to issue another one. Is it permissible to dispatch an event from inside an event handler?

mikethompson23:03:00

@jmckitrick yes, you'd use the :dispatch effect.

mikethompson23:03:43

But you wouldn't use dispatch directly, because that would be sideeffecting

jmckitrick23:03:02

Hmm. So what’s the correct way?

mikethompson23:03:15

BTW, there is also a #re-frame channel

jmckitrick23:03:15

Ah, perfect.

mikethompson23:03:32

Be sure to read the docs :-)

jmckitrick23:03:27

Will do, thanks for the reminder. I’m working my way through the Eric’s videos, and forgot about the deep docs I hadn’t gotten to yet.

jmckitrick23:03:47

That’s one area where re-frame shines: the docs

exit223:03:39

Is there any preferred library for handling global state w/ reagent?

justinlee23:03:27

I use specter

justinlee23:03:52

it takes a little bit of getting use to, but the code is easy to read once you have it going