Strategies for server-side rendering of asynchronously initialized React.js components
If you use react-router, you can just define a willTransitionTo
methods in components, which gets passed a Transition
object that you can call .wait
on.
It doesn't matter if renderToString is synchronous because the callback to Router.run
will not be called until all .wait
ed promises are resolved, so by the time renderToString
is called in the middleware you could have populated the stores. Even if the stores are singletons you can just set their data temporarily just-in-time before the synchronous rendering call and the component will see it.
Example of middleware:
var Router = require('react-router');
var React = require("react");
var url = require("fast-url-parser");
module.exports = function(routes) {
return function(req, res, next) {
var path = url.parse(req.url).pathname;
if (/^\/?api/i.test(path)) {
return next();
}
Router.run(routes, path, function(Handler, state) {
var markup = React.renderToString(<Handler routerState={state} />);
var locals = {markup: markup};
res.render("layouts/main", locals);
});
};
};
The routes
object (which describes the routes hierarchy) is shared verbatim with client and server