Hacker News new | past | comments | ask | show | jobs | submit login
Flux Comparison by Example (github.com/voronianski)
145 points by ksmtk on Feb 3, 2015 | hide | past | favorite | 55 comments



Anyone tried doing isomorphic (server/client) flux?

Most implementations rely on the flux stores being singletons which can't work for multiple requests on the server.

The only one that's isomorphic is yahoo's but that one feels terribly verbose.


The verboseness is yahoo's is really quite superficial. F.ex. on a day to day basis, you're not spending hours and hours adding action constants.

I've been making an app based on yahoo's dispatchr (part of fluxible) for about 4 months now, and I hardly spend time with the "verbose" part of my app. All the real work is in data fetching, view rendering, business logic, and so on.

Really, if there's X libraries out there and X-1 don't support isomorphic apps, and the only complaint you can come up with about the one that does is that the most boring, logic-free and error-free part of your app will look a little verbose, then what are you still waiting for?


Alt[1] has isomorphic support but there are some trade offs such as you're unable to use actions on the server. But you can still keep your stores as singletons and have them be concurrent. I'm still juggling on different ways to tackle this problem to offer more flexibility. There are a couple of example apps sitting in the iso[2] repo which is an isomorphic helper class.

1: https://github.com/goatslacker/alt

2: https://github.com/goatslacker/iso/tree/master/examples


I've not used flux for my demo, but it is isomorphic, loads data asynchronously (something many isomorphic examples skip over), and has a very simple version of Yahoo's data hydration / dehydration.

I imagine you could extend this to use Flux relatively easily - most of the hard stuff is done, and the code base is quite small.

https://github.com/davedx/isomorphic-react-template


No reason why it couldn't work on the server: create multiton versions of stores and when a page is ready to be rendered assign the state of the multiton instances to the corresponding singleton instances, call render and return the singleton instances to their previous states. Sure it's hacky as hell but just hide it somewhere, there is no reason to do it manually in application code.


Here's a demo I put together:

https://github.com/appsforartists/ambidex-example--bike-inde...

It instantiates a new Reflux store for each request, and uses data in the URL to figure out which stores to populate before rendering.


The singletons are only problematic if you need to interact with them asynchronously. `React.renderToString` is synchronous, so there's no reason stores have to be async.

Shameless plug: Fynx[0] is mostly synchronous, for example.

[0]: https://www.npmjs.com/package/fynx


Fynx is what I'm using in my project. It'd be nice to get it added to the comparison.


but how would you deal with async data fetches then?

I want to have the same routing and data fetching logic both on the client and on the server, and for that I would need to have stores that are independent for different incoming HTTP requests.


I'm not sure how you're supposed to do it, but that hasn't been a problem for me. I set up two actions: load and init. load starts a request and init sets the data in the store.


Stores should be definitely sync in any implementation!


Another shameless plug: Flummox deals with this by eschewing singletons https://github.com/acdlite/flummox. Along with built in promise support, it works really well with react-router's lifecycle methods.


Nice to see more singleton free Flux libraries! My experience is also that it's almost impossible to make isomorphic apps with singleton based designs. Too bad the original Facebook version used singletons and everybody copied it. Big mistake.

Btw. I would love to see a full example of an isomorphic Flummox application using react-router.


Yeah absolutely. I'm going to try to work this weekend on some demos. Still trying to figure out a good solution for over-fetching. It's a tough problem... which is why Relay looks so, co cool.


You can see an example of Fluxible with react-router: https://github.com/yahoo/flux-examples/tree/master/react-rou...


Whipped together a basic one last night: https://github.com/acdlite/flummox-isomorphic-demo


This looks really nice! I haven't understood why this pattern hasn't been the default all along. Singletons are not a pattern used very often in JS so I'm not sure why it caught on in Flux.


Thanks! Yeah, I don't get it either. I think esamatti is exactly right: the original Facebook example used singletons and everyone followed their lead.

That, combined with the fact that all CommonJS modules are singletons, anyway.


All JavaScript modules are singletons regardless of the format. But it's still a very common practice to export a constructor function as the module's value and then to instantiate new instances. No idea why that hasn't been followed with React, but I imagine that you are correct about the Facebook example. They should have put more care into making it correct rather than just making it simple to explain.


Yep, that's what I was trying to say. The require cache makes the singleton pattern extra alluring, even in cases where you should avoid it.


There's another demo here: https://github.com/zertosh/ssr-demo-kit


I am using Yahoo's fluxible app and it is quite good. Doesn't feel verbose at all in every day use.


I completely agree that Fluxible feels very verbose.. Did you try Reflux.js?


reflux.js isomorphic support is still in flux https://github.com/spoike/refluxjs/issues/144


(fluxible dev here)

Which part of Fluxible feels verbose?


- dispatching and listening to actions. you need to pack your action with a magic string and a param object then unpack the params again in every listener. It's easy to forget what the params names are and its hard to see what the function gets as params just from its signature.

It would be much nicer to have e.g.:

   context.actions.myAction('foo', 'bar')
And

   onMyAction: function(foo, bar)
- dealing with asynchronous data fetches. The example shows that you should create 3 actions for every async data action: FETCH_STARTED, FETCH_COMPLETE and FETCH_ERROR.

How would you deal with cases where you need to fetch multiple data sources then combine them? Seems like the number of actions would quickly explode. Also, how would you deal with dependencies and errors?

- the service api:

    context.service.read('message', {}, {}, function (err, messages)
too many optional params, kinda hard to keep track what goes where.

I'd prefer something with promises.

- I also miss query params support in fluxible router


For me, it's really the part where you end up having to wrap up all of your actions with `context.executeAction`.

It would be cool if there was a nice way that you could wrap an action with a function to generate that boilerplate for you, similar to how Bluebird's `Promise.promisify(myFunction)` generates a Promise-wrapped function for anything following the typical Node callback style.


It's great to see more example Flux projects using different implementations, but what we really need is just one larger and more sophisticated app example.

I've been adapting a React-based app to the Flux architecture for the last week or two. I constantly find myself scratching my head, especially regarding asynchronous operations that need to be reflected in the View.

It would be nice for the mock API in these examples to "simulate" a poor network connection in order to see how asynchronous error handling is best handled in each implementation, for instance.


That's why we created https://github.com/jhollingworth/marty-chat-example. It's got proper examples of using HTTP & WebSockets


Ha, I actually submitted an issue to this yesterday. It's a good example but misses some really important (i.e. usually-confusing) stuff: error/failure handling and rollbacks.


Is there a formal spec for a "flux application"? Or what's the common denominator here?



@prottmann alluded to it, but it might be useful to add Marty as well (http://martyjs.org) (no affiliation).

It's just behind Reflux on the superficial metrics (stars, contributors, npm downloads) so is likely to be on most short-lists.

I've had a good experience with Marty so far but remain curious about the others. Reflux worries me a bit because of its minor divergences from the Flux design decisions.


I've opened a PR for it but it needs to be merged in https://github.com/voronianski/flux-comparison/pull/5


Could you elaborate on your worries? I've used Reflux because it simplified certain things, and I'd love to understand the drawbacks.


Same thing here. Marty is proving to be very good and flexible so far while providing a rather succinct implementation overall. +1



This is pretty cool. There have been a ton of flux frameworks floating around lately, glad that there's an app that deals with async data to be able to compare each on their merits.


Thank you! Yesterday i thought about something similar -> a comparison of different flux implementations with an example (and not with a todo-app).

I tried some sample apps in the last weeks with reflux, fluxxor and now marty to see the practical differences.


Great job! It's nice to be able to compare same application elements written in different frameworks - very illustrative.

Can't wait for the post with conclusion and thoughts on this.


I'm surprised to discover how useful I found this -- being able to compare roughly 'apples to apples' in an app was very helpful. Thank you for your efforts!


Is there a conclusion, comparison or a point? I'm interested in the outcome but not trawling through the links and stuff.


there will be summing up article soon, but that's not the main point


I would also like your know thoughts on how they compare.


So, which one do you prefer and why ?


Where do people think up these names: Reflux? http://en.wikipedia.org/wiki/Gastroesophageal_reflux_disease

Why don't we have a library called Melanoma or HIV yet? Actually I am sure we do have libraries with these names somewhere on github.


To be fair, the word 'reflux' does have significant meaning outside the context of gastrointestinal disease. I agree some people might have unpleasant associations to the word, but for me this is the first thing that comes to mind: https://en.wikipedia.org/wiki/Reflux


As someone suffering from non-erosive esophageal reflux disease (N.E.R.D., btw), I take no offense from one of the libraries being called Reflux.

Drama much?


Well, there's Mono...


A language runtime for Unix systems...


It gives me an uneasy feeling too. It's slightly better than calling a library Vomit.js.


Who knows? Bunch of cheeky bastards with a flux capacitor obsession really.


Bigger issue is that utility f.lux.


I once saw someone rant for pages and pages about how "flux" was a terrible name for anything because it was an archaic term for diarrhea.


haha that's funny! because recently I had reflux disease :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: