Last active
February 13, 2016 18:02
-
-
Save jeffhandley/9dcfe349319fc3583161 to your computer and use it in GitHub Desktop.
A pattern for server-side async data loading with React components
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
export default (req, res, callback) => { | |
// Do async work, consuming data off req if needed | |
// Potentially set headers or other data on res | |
// When all the data is loaded, call the callback with the component | |
callback(React.createClass({ | |
render() { | |
return ( | |
<html> | |
<head /> | |
<body /> | |
</html> | |
); | |
} | |
})); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactDOMServer from 'react-dom/server'; | |
import express from 'express'; | |
import loadPage from './page'; | |
const app = express(); | |
app.get('/', (req, res) => { | |
loadPage(req, res, (Page) => { | |
res.send(ReactDOMServer.renderToStaticMarkup(<Page />)); | |
}); | |
}); | |
app.listen(3000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With the server rendering isolated containers of React content that can be universally rendered, it's time to determine what else we will need to accomplish that universal rendering.
Each universally-rendered container is likely to require:
This is where the react-composite-pages project (npm package) comes in. React-Composite-Pages introduces a
<RenderContainer />
component that allows React components to be encapsulated in universal rendering containers, with their state and client scripts tagging along (but rendered into the page structure where the page template dictates). React-Composite-Pages is ignorant of any flux implementation choice--it can be used with any flux implementation or even without one.Modifying the page and the page template from above to use React-Composite-Pages has the following result.
page.js
template.js
If we examine the HTML that comes out of this we'll see:
If you're wondering, the
<noscript>
tags are the result of using react-side-effect withinRenderContainer
to "export" the state and clients. EachRenderContainer
actually emitted a<RenderState>
and<RenderClient>
component (from react-composite-pages) into the component hierarchy, but they don't result in any rendered content--instead, they contribute to thetemplate.state
andtemplate.clients
components that came out of therenderTemplate()
function.As you can see here, react-composite-pages provides a useful
RenderContainer
component that can be used to apply this pattern of universal rendering containers that each have their own state and clients.From here, the next step is to jump into the examples provided in the GitHub project for React-Composite-Pages and see how this comes together with flux implementations (there are redux and fluxible pages), webpack, and completing the client-side rendering.