jmreidy / fluxy

An implementation of Facebook's Flux architecture
232 stars 19 forks source link

Make `renderStateToString` an instance method #22

Open jmreidy opened 10 years ago

jmreidy commented 10 years ago

See discussion on #1.

bgoldman commented 10 years ago

I'm still confused about how this would solve the concurrency/data race condition discussed in the other issue.

While you could make renderStateToString an instance method and call that method from a Fluxy instance, if the Fluxy instance has any data being requested asynchronously, it still appears that the problem remains. Specifically, any Fluxy instance that needs data from an asynchronous source would likely use a store to fetch the data, like TodoStore.get('todos'), and this is called statically, not as an instance method. The store will be storing this data globally, not as part of the specific instance for the request.

If two users make a request at the same time, we run into this problem again.

Is it possible to avoid this? Do you have a potential solution, now, or in the pipeline?

jmreidy commented 10 years ago

Ah, I see what you mean here. Fluxy assumes that all store interactions are synchronous. Any async data loading should happen via an action/service interaction that then populates the Store(s).

Pre-rendering on the server ONLY works when you create the entire data graph for rendering the current state of the page. If you're missing a part of the data graph, and rendering a component triggers an action to pull in more data, you're going to run into problems, definitely.

bgoldman commented 10 years ago

If we do async data loading via actions/services as you say, and then populate the stores, I'm still confused as to how this avoids the concurrency issue. If two requests come in at the same time and both try and populate the same store, but with that request's user instance, wouldn't that be a problem?

jmreidy commented 10 years ago

It's two different approaches between client and server.

On the client, user behavior triggers actions that populates data (usually asynchronously) in stores. The rendered components pull data from these stores.

On the server, asynchronous data loading (via some combination of DB, cache, services, etc) creates a data graph that is passed to Fluxy and then the component state is rendered to string.

So on the server, we're basically doing static page generation based on previously loaded data; on the client, we're dynamically loading the data on the fly.

The ONLY time you'd be using the pre-rendered page is on initial landing.

The "Fluxy" on the server isn't doing anything on individual client machines; Fluxy is only used on the server to pre-render component state for a static view of a landing page.

Hopefully that makes a bit of sense.

bgoldman commented 10 years ago

On the server, we still use the user's cookie to make async calls on their behalf for data from databases/APIs/etc, and do so via actions/services. Would you not do so via actions/services?

To clarify further, we want to be able to render on the server for any request from any URL, not just on a specific landing page. If someone is on any page on our site and bookmarks it, and then goes back, we want to pre-render that page on the server and then subsequent clicks would be rendered client-side.