Last active
May 22, 2017 08:31
-
-
Save blackfry/36659ed6a16aa161063c8d1e0efa288d to your computer and use it in GitHub Desktop.
server rendered with react router
This file contains 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 {renderToString} from 'react-dom/server'; | |
import {StaticRouter} from 'react-router-dom'; | |
import {createStore} from 'redux'; | |
import {Provider} | |
import 'react-redux'; | |
import reducer from 'reducer.js'; | |
import App from 'App.js'; | |
const app = new Express() | |
const port = 3000; | |
app.get(/^\/.*/, (req, res) => { | |
let config = buildAPIConfig(req); | |
// component doesn't get rendered until fetch promise is resolved with initial data | |
getAsyncData(config) | |
.then(apiResult => { | |
const context = {}; | |
let preloadedState = apiResult; | |
const store = createStore(reducer, preloadedState); | |
const html = renderToString( | |
<Provider store={store}> | |
<StaticRouter | |
location={req.url} | |
context={context}> | |
<App/> | |
</StaticRouter> | |
</Provider> | |
); | |
if (context.url) { | |
res.writeHead(301, { | |
Location: context.url | |
}); | |
res.end() | |
} else { | |
const finalState = store.getState(); | |
res.set('content-type', 'text/html'); | |
res.send(renderFullPage(html, finalState)); | |
} | |
}) | |
.catch(err => res.writeHead(400, { | |
Location: context.url | |
})) | |
}); | |
app.listen(port, (error) => { | |
if (error) { | |
console.error(error) | |
} else { | |
console.info(`Listening on port ${port}. Open up http://localhost:${port}/ in your browser.`) | |
} | |
}); | |
const getAsyncData = config => { | |
return fetch(config.route, config.options) | |
}; | |
const buildAPIConfig = req => { | |
return { | |
route: req.route, | |
options: { | |
method: 'GET', | |
header: { | |
// | |
} | |
} | |
} | |
}; | |
const renderFullPage = (html, finalState) => { | |
return ` | |
<!doctype html> | |
<html> | |
<head> | |
<title>Redux Universal Example</title> | |
</head> | |
<body> | |
<div id="root">${html}</div> | |
<script> | |
// WARNING: See the following for security issues around embedding JSON in HTML: | |
// http://redux.js.org/docs/recipes/ServerRendering.html#security-considerations | |
window.__PRELOADED_STATE__ = ${JSON.stringify(finalState).replace(/</g, '\\u003c')} | |
</script> | |
<script src="/static/bundle.js"></script> | |
</body> | |
</html> | |
` | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment