Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.




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

Search: