Mike Haney
unread,Dec 11, 2014, 4:15:04 PM12/11/14Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to clojur...@googlegroups.com
There's nothing wrong or inefficient with using a single atom for your state in Reagent. I do that more often than not, and it works fine. As I understand it, the Reagent model is this: when you deref an atom, that is Reagent's cue to re-render any components that reference that atom (actually it schedules a render for the next animation frame, just like Om). Within a component, Reagent caches the props for each child component and will only re-render the children whose values have changed. So in a scenario where you have a single atom, and let's assume every component references it, then yes, every component could potentially be re-rendered but the caching prevents any extra rendering happening at the React level.
So, although the exact mechanism used is different between Om and Reagent, the end result is the same - they both use the power of immutable data structures to do simple equality checks for Reacts should-update method. One nice thing about the Reagent model is that you still have the option of splitting your state up if you want, either to control the scope of re-renders or just simply because that model fits your app better. It's also important to remember that React itself is very fast, even without these optimizations - by far your biggest gains come from React's diffing to minimize DOM updates, the rest is just icing on the cake.
With regards to state management, I still see 2 big advantages to the Reagent model. First is that core.async is just not needed like it is with Om. If you need core.async for other parts of your app, fine - I still use it for Ajax calls and all those other things where it's wonderful, but there's no need to rely on it for inter-component communication like you usually end up doing with Om.
Second, I really like how local state is also just an atom. This makes it so much easier to reason about your code - no more need to track "is this a cursor or a value" or "am I in the render phase or not". It also makes it easier to write supporting functions and compose them (in Om, start composing functions that take cursors and then if you need to use them outside the render phase - oops!).
As for the specific question about where to create core.async channels (if you can't or don't want to eliminate them) - I posted a gist in one of your earlier threads where I showed how I register subscribers in a closure, just like creating local state. This will work in some cases (top level components that exist for the lifetime of the page) but in general it's not a good thing to do because the go blocks are never cleaned up (my mistake, hope I didn't cause problems for anyone who followed that example). The proper way to do that is in will-mount/unmount, just as in Om. In Reagent, you attach lifecycle functions using either create-component or by attaching metadata. The metadata approach isn't as bad as I originally thought - you can generally write nice generic functions to wrap your components and attach metadata, similar to the mix-ins in Om-tools.
Finally, I don't know if you're aware, but Reagent recently moved to a github org at reagent-project, and things have really been moving. Dan did a great job with Reagent, but was too busy to give it the love it deserved and graciously created the org and brought in more contributors, and the results are already impressive. There are more resources there, including a cookbook and lein template. And the new 5.0 alpha they just released has some nice goodies, my favorite being the ability to use regular React components within your Reagent components. I've also been following closely the conversations between Dmitri, Sean and the other contributors and I like the direction they are headed in (and hope to start contributing myself soon). When I first considered switching to Reagent, my only concern was the relative lack of activity, but that's no longer an issue at all.