I've read on http://scotch.io/tutorials/javascript/build-a-real-time-twitter-stream-with-node-and-react-js and it describes a technique of taking over server rendered React components seamlessly:
Server renders into {{{markup}}} in handlebars, and pass initial state.
<section id="react-app">{{{ markup }}}</div>
<script id="initial-state" type="application/json">{{{state}}}</script>
Then on the client side javascript
/** @jsx React.DOM */
var React = require('react');
var TweetsApp = require('./components/TweetsApp.react');
// Snag the initial state that was passed from the server side
var initialState = JSON.parse(document.getElementById('initial-state').innerHTML)
// Render the components, picking up where react left off on the server
React.renderComponent(
<TweetsApp tweets={initialState}/>,
document.getElementById('react-app')
);
But in a flux architecture, such as described in this article http://scotch.io/tutorials/javascript/creating-a-simple-shopping-cart-with-react-js-and-flux, state is initialized in the getInitialState lifecycle method:
// Method to retrieve state from Stores
function getCartState() {
return {
product: ProductStore.getProduct(),
selectedProduct: ProductStore.getSelected(),
cartItems: CartStore.getCartItems(),
cartCount: CartStore.getCartCount(),
cartTotal: CartStore.getCartTotal(),
cartVisible: CartStore.getCartVisible()
};
}
// Define main Controller View
var FluxCartApp = React.createClass({
// Get initial state from stores
getInitialState: function() {
return getCartState();
},
// Add change listeners to stores
componentDidMount: function() {
ProductStore.addChangeListener(this._onChange);
CartStore.addChangeListener(this._onChange);
},
// Remove change listers from stores
componentWillUnmount: function() {
ProductStore.removeChangeListener(this._onChange);
CartStore.removeChangeListener(this._onChange);
},
// Render our child components, passing state via props
render: function() {
return (
<div className="flux-cart-app">
<FluxCart products={this.state.cartItems} count={this.state.cartCount} total={this.state.cartTotal} visible={this.state.cartVisible} />
<FluxProduct product={this.state.product} cartitems={this.state.cartItems} selected={this.state.selectedProduct} />
</div>
);
},
// Method to setState based upon Store changes
_onChange: function() {
this.setState(getCartState());
}
});
module.exports = FluxCartApp;
Which one is the right approach to setting state from a progressive enhancement point of view?
Thinking about progressive enhancement I like how flux and react work together.
I am using ReactJS and Flux in my current project and everything is clean and easy. All you have to be aware of is showing some discipline of creating new stores when it really is needed. I dont really like the eventEmitter stuff though. I just trigger my own events which I define in a seperate eventConstants.js file this allows me to have several components listening for different changes on the same store.
This really scales well.
Answering your question:
It does depend about your usecase. Ignoring that rendering an initial page on the server is great for SEO it does only make sence to render on the server if users should all see pretty much the same content. I like to keep client stuff on the client.
I hope this helped you