Fork me on GitHub

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:


@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).


@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 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?


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...


@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 so can tell nothing about that.


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.


Don't forget that React itself is quite fast simple_smile


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


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.. 😄


@nidu thnx for discussing


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.


@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


@not-much-io: recently ended up implementing something similar, might be of interest:


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


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


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


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


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


@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


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


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


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


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


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


and then a single boolean will not help simple_smile


@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 ..]


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


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


@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.


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


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


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


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


@leonfs: you add some pushstate routing or similar


… interesting..


@leonfs: if is interesting, you may also be interested in a re-frame version of it


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


@josh.freckleton: maybe datascript?


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


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


but maybe i'm not understanding your question


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


@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.