Skip to content

Commit 31d1a6e

Browse files
petehuntryanflorence
authored andcommitted
[added] renderComponentToString()
closes #36
1 parent d6b7e22 commit 31d1a6e

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

Diff for: modules/Router.js

+19
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,25 @@ mergeProperties(Router.prototype, {
208208
return component;
209209
},
210210

211+
/**
212+
* Renders this Router's component as a string. Since this may be an asynchronous
213+
* process, this returns a Promise.
214+
*/
215+
renderComponentToString: function(path) {
216+
invariant(
217+
!this.state.props,
218+
'You may only call renderComponentToString() on a new Router'
219+
);
220+
221+
return this.dispatch(path).then(function() {
222+
var route = this.route;
223+
var state = this.state;
224+
var descriptor = route.handler(state.props);
225+
var markup = React.renderComponentToString(descriptor);
226+
return markup;
227+
}.bind(this));
228+
},
229+
211230
handleRouteChange: function () {
212231
this.dispatch(URLStore.getCurrentPath());
213232
}

Diff for: specs/Router.spec.js

+40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require('./helper');
2+
var Promise = require('es6-promise').Promise;
23
var Router = require('../modules/Router');
34
var RouteComponent = require('../modules/components/Route');
45

@@ -125,6 +126,45 @@ describe('a Router with custom props', function() {
125126
});
126127
});
127128

129+
describe('a Router that renders on the server', function() {
130+
it('works with async willTransitionTo()', function(done) {
131+
var dataStore = 'goodbye';
132+
var Layout = React.createClass({
133+
render: function() {
134+
return React.DOM.article(null, this.props.activeRoute);
135+
}
136+
});
137+
var AsyncApp = React.createClass({
138+
displayName: 'AsyncApp',
139+
statics: {
140+
willTransitionTo: function() {
141+
return new Promise(function(resolve) {
142+
setTimeout(function() {
143+
dataStore = 'hello';
144+
resolve();
145+
}, 0);
146+
});
147+
}
148+
},
149+
render: function() {
150+
return React.DOM.div(null, dataStore);
151+
}
152+
});
153+
154+
var router = Router(
155+
RouteComponent({ path: '/', handler: Layout},
156+
RouteComponent({ path: '/a', handler: AsyncApp }))
157+
);
158+
159+
router.renderComponentToString('/a').then(function(result) {
160+
expect(result.indexOf('div') > -1).toBe(true);
161+
expect(result.indexOf('hello') > -1).toBe(true);
162+
163+
done();
164+
});
165+
});
166+
});
167+
128168
function lastItem(array) {
129169
return array[array.length - 1];
130170
}

0 commit comments

Comments
 (0)