Fork me on GitHub
#re-frame
<
2016-03-22
>
not-much-io08:03:26

As I understand, re-frame suggest using a single global state atom, which I can get behind. But I am wondering about best practices and something that screams "local state!". Example, I have a message feed that has auto scroll functionality that is toggled on clicking the feed. Do I store my "minor local concerns" in the global state, create the handlers and subscriptions or is there a different way to handle such cases? gist example: https://gist.github.com/not-much-io/ca35ce3570c3a1bdd4c5

nidu08:03:20

@not-much-io: You can introduce local ratom to store it and change it on click. Or you can move this info to it's parent by accepting this state as argument and rely on some smart component in component hierarchy. Dispatchers/subscriptions sacrifice some reusability IMHO, but i as far as i can tell it's the only approach to preserve app state if you're doing reloadable app with deep reload (i mean when entire component tree is recreated).

not-much-io08:03:09

@nidu I realize I could use a local ratom, but is this good style? I can imagine it biting me in the ass (ratoms everywhere), but I don't have experience to back that up. simple_smile (Not really seeing the value of deep reload for me right now, but you never know.. ) How about Om.next-s style? Root takes most of the tree and passes necessary data down to its children as needed. Will this trigger unnecessary reloads in parents, if the subscription would only affects a child?

vikeri09:03:01

A question about modelling the db atom. I have a normal postgres db with relations. Do I model my atom after this (ie. put the id on the foreign key) or do I model it like an active record: ie. replace the foreign key with the object itself? I know datascript would probably have been a good solution for this but apparently it is too slow on React Native...

nidu10:03:16

@not-much-io: can tell the same about my experience. For me deep reload looks better because i don't have to do anything to reload current subscriptions/dispatchers after editing sources. Haven't worked with om.next so can tell nothing about that.

nidu10:03:32

However reagent docs says: Mounted components are only re-rendered when their parameters have changed. So i don't think it will affect performance significantly.

nidu10:03:40

Don't forget that React itself is quite fast simple_smile

not-much-io10:03:52

@nidu I'm probably doing premature optimization, but I'd like to try to get the basics more or less right from the start. 😄

not-much-io10:03:04

I'll probably going to stick to typical re-frame style with local ratoms for things that scream "local concern!". I might move the local concerns to the global state at a later time. Experience will teach me! .. Hopefully.. 😄

not-much-io10:03:27

@nidu thnx for discussing

not-much-io11:03:51

Ofcourse, I could make my own, that would just return a subscription to the parameter key.

(re-frame/subscribe [:simple-sub :x])  ; sub to :x
(re-frame/subscribe [:simple-sub :y])  ; sub to :y
Yup, may be what I want.

nberger15:03:40

@danielgrosse: menu-container should be a Form-1 component (should return just hiccup). It's a Form-2 (it's returning a fn that returns hiccup). Even thought it's not necessary, it could work as Form-2, but in that case the inner fn should receive menu-data too

martinklepsch16:03:26

@not-much-io: recently ended up implementing something similar, might be of interest: https://gist.github.com/martinklepsch/9565a5ea099c44bc2931

not-much-io16:03:14

@martinklepsch: Oh, nice. Thnx, I'll have a look simple_smile

martinklepsch16:03:08

I chose the local state approach because I the state I'm using (should this thing scroll?) is fine to lose + I didnt want to clutter my db with it simple_smile

martinklepsch16:03:40

"fine to lose" as in "lose during a hot reload"

not-much-io16:03:22

Yeah, I was thinking the same. Much cleaner this way. simple_smile

not-much-io16:03:13

@martinklepsch: Couldn't we avoid losing the state during hot reloading by using a method like defonce?

martinklepsch16:03:05

@not-much-io: if you define the atom outside of the component yes. Then however you'd also need some logic that handles multiple components

martinklepsch16:03:26

i.e. your atom would not contain a boolean but a map like {:component-a false} etc

martinklepsch16:03:48

@not-much-io: if you really want to work around it it's definitely possible simple_smile

not-much-io16:03:26

@martinklepsch: But why a map and not a boolean?

not-much-io16:03:35

I'd think defonce for state local to the file would work? Yes ofcourse if adding more than just one state variable.

martinklepsch16:03:07

@not-much-io: if you manage state globally you'd need to account for the situation that the component is rendered multiple times

martinklepsch16:03:22

and then a single boolean will not help simple_smile

not-much-io16:03:35

@martinklepsch: Are you refering to something that has to do with react lifecycle methods / Type 3 forms ? As I can't figure out what would break with a Type 1:

(defonce scrolling? (r/atom false))

(defn comp []
  (if @scrolling
    ..)) ; Do something if yes or no
  [:div ..]

martinklepsch16:03:13

@not-much-io: the moment I have to comp components rendered it breaks simple_smile

martinklepsch16:03:41

unless you want that scrolling state to be identical for all rendered components

not-much-io16:03:39

@martinklepsch: Aaa, yes ofcourse. For me I was just thinking of one scroll state for a single element. For that it would work. For multiple element it would have to be a a map of key/id -> state or smth.

leonfs16:03:56

Does anybody know a good practices on how to achieve good SEO with re-frame?

leonfs16:03:54

I’ve achieved really good results using angular and http://prerender.io (replacing #! for escapedfragments_) but I don’t see that #! is used at all when using re-frame

martinklepsch16:03:29

@leonfs: you can use #! with re-frame, it's just that re-frame is not concerned with routing at all

leonfs16:03:33

how would you achieve permalinks/bookmarks on re-frame?

martinklepsch17:03:37

@leonfs: you add some pushstate routing or similar

leonfs17:03:18

… interesting..

mikethompson20:03:03

@leonfs: if is interesting, you may also be interested in a re-frame version of it https://github.com/pupeno/prerenderer

josh.freckleton21:03:06

how do I query a db using re-frame, without building a ton of handlers and API endpoints for each resource?

oli21:03:54

@josh.freckleton: maybe datascript?

josh.freckleton21:03:23

@oli: I looked at that, but I thought it was like a local, client-only database, no?

oli21:03:17

yeah - but the content of the client side db can come from anywhere - e.g. a datomic db on the server

oli21:03:36

but maybe i'm not understanding your question

oli21:03:07

(i assumed you meant the client side app-db)

josh.freckleton22:03:46

@oli: I don't understand what a client-side db wins me, over re-frame's db atom. I'm wondering about querying the backend db without writing a ton of handlers and endpoints.