A minimal sample full-stack React app using express, iso, react-router and iniquest.
One of the biggest challenges with full-stack react for me was/is asynchronous data fetching before rendering on the server while keeping components as pure as possible. Let me try and explain how I approached it:
For this little app, the tree of RouteHandler
s goes like this:
<Route handler={App}>
<Route name="home" path="/" handler={Home} />
<Route name="markdown" path="/markdown" handler={Markdown} />
<Route name="ip" path="/ip" handler={Ip} />
</Route>
Every RouteHandler
can optionally implement a static
method called prepareForRequest(req)
where req
is the request object coming from the express middleware. Here is how the Ip
component implements this method to fetch the server's ip address before a render (I stripped out all the client-side code for the readme here):
class Ip extends React.Component {
render() {
return <div>Your ip is: {this.state.ip}</div>;
}
}
mixin.onClass(Ip, iniquest.InitialStateFromProps);
Ip.prepareForRequest = function() {
return axios.get('http://ip.jsontest.com').then(res => res.data);
};
In server.js
there are about 10 lines of code that make this possible. If the Ip
component had a child RouteHandler
with its own prepareForRequest
method, it could pass through the child state through props by mixing in iniquest.InitialChildState
.
<RouteHandler initialState={this.initialChildState} />
$ npm install
$ npm start
The server will listen on port 3000
or the one specified in the environment variable PORT
.