- Data fetching for universal JS apps is hard. If you do any XHRs their data isn't present in the server-rendered markup.
- Often you will want to send down the initial state of the app along with the webpage that bootstraps it.
- The Relay "n+1 queries problem". It's possible for you to stumble into really inefficient data fetching patterns with this. You should build some sort of batching abstraction on top of this.
- Client-side mutations (use Flux + this)
Declaratively specify your XHRs:
var React = require('react');
var ReactXhr = require('react-xhr');
var MyComponent = React.createClass({
mixins: [ReactXhr.Mixin],
getXhrs: function() {
return {
userInfo: {
url: '/user/' + this.props.username,
method: 'get',
},
};
},
render: function() {
return <div>User info: {this.state.xhrs.userInfo.body}</div>;
},
});
this.state.xhrs.X
has the following properties:
loading
: true or false if there's a pending requesterr
: any error object associated with the most recent requestbody
: parsed JSON response returned from the server, empty object if no response yet.
This in and of itself is pretty great, but you can render it server-side if you provide your own function to resolve the fetching:
// On the server
function mockXhrs(xhrs, cb) {
// Mock backend call
var response = {};
for (var xhrId in xhrs) {
var xhr = xhrs[xhrId];
if (xhr.url.indexOf('/user/') === 0) {
response[xhrId] = {username: xhr.url.slice('/user/'.length), isCool: true};
}
}
cb(response);
}
ReactXhr.renderToString(
<MyComponent username="floydophone" />,
mockXhrs,
function(err, result) {
console.log(result.markup);
console.log(result.preloadedData);
}
);
Now that you have the markup and data that you need to preload on the client, you can render on the client easily:
// On the client
ReactXhr.render(<MyComponent username="floydophone" />, preloadedData);
You can do other types of requests, not just xhrs. getXhrs()
just returns a description of what to
fetch. You can plug in your own if you want to do fetching via websocket, batched fetching, etc.
// On the client
ReactXhr.overridePerformXhr(function(xhr, cb) {
// Read properties off of xhr (as returned from getXhrs()) and call cb(err, body)
// with the results
});