Last active
April 26, 2018 16:24
-
-
Save btholt/01adb3cf9c114e5b46a0 to your computer and use it in GitHub Desktop.
react-router server-side rendering
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
require("babel-register") | |
var express = require('express') | |
var React = require('react') | |
var ReactDOMServer = require('react-dom/server') | |
var ReactRouter = require('react-router') | |
var match = ReactRouter.match | |
var RouterContext = ReactRouter.RouterContext | |
var _ = require('lodash') | |
var fs = require('fs') | |
var port = 5050 | |
var baseTemplate = fs.readFileSync('./index.html') | |
var ClientApp = require('./js/ClientApp.jsx') | |
var routes = ClientApp.Routes | |
var app = express() | |
app.use('/public', express.static('./public')) | |
app.use((req, res) => { | |
// Note that req.url here should be the full URL path from | |
// the original request, including the query string. | |
match({ routes: ReactRouter.createRoutes(routes), location: req.url }, (error, redirectLocation, renderProps) => { | |
console.log(error, redirectLocation, renderProps) | |
if (error) { | |
res.status(500).send(error.message) | |
} else if (redirectLocation) { | |
res.redirect(302, redirectLocation.pathname + redirectLocation.search) | |
} else if (renderProps) { | |
// You can also check renderProps.components or renderProps.routes for | |
// your "not found" component or route respectively, and send a 404 as | |
// below, if you're using a catch-all route. | |
res.status(200).send(ReactDOMServer.renderToString(React.createElement(RouterContext,renderProps))) | |
} else { | |
res.status(404).send('Not found') | |
} | |
}) | |
}); | |
console.log('listening on ' + port) | |
app.listen(port) |
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
const React = require('react') | |
const Landing = require('./Landing') | |
const Search = require('./Search') | |
const Layout = require('./Layout') | |
const Details = require('./Details') | |
const ReactRouter = require('react-router') | |
const data = require('../public/data') | |
const { Router, Route, hashHistory, IndexRoute } = ReactRouter | |
const Store = require('./Store') | |
const { store } = Store | |
const reactRedux = require('react-redux') | |
const { Provider } = reactRedux | |
const shows = data.shows || [] | |
const MyRoutes = (props) => ( | |
<Route path='/' component={Layout}> | |
<IndexRoute component={Landing} /> | |
<Route path='/search' component={Search} shows={shows} /> | |
<Route path='/details/:id' component={Details} onEnter={props.assignShow} /> | |
</Route> | |
) | |
class App extends React.Component { | |
constructor (props) { | |
super(props) | |
this.assignShow = this.assignShow.bind(this) | |
} | |
assignShow (nextState, replace) { | |
const show = data.shows[nextState.params.id] | |
if (!show) { | |
return replace('/') | |
} | |
Object.assign(nextState.params, show) | |
return nextState | |
} | |
render () { | |
return ( | |
<Provider store={store}> | |
<Router history={hashHistory}> | |
<MyRoutes assignShow={this.assignShow} /> | |
</Router> | |
</Provider> | |
) | |
} | |
} | |
App.Routes = MyRoutes | |
module.exports = App |
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
{ | |
"name": "complete-intro-to-react", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"build": "webpack", | |
"watch": "webpack --watch", | |
"test": "mocha --require test/helpers/setup.js", | |
"lint": "eslint --ignore-path .gitignore --cache ./", | |
"cover": "nyc --reporter=lcov --reporter=text --reporter=html --require babel-register --extension .jsx npm test" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"express": "4.13.4", | |
"lodash": "4.6.1", | |
"react": "^0.14.7", | |
"react-dom": "^0.14.7", | |
"react-redux": "^4.4.0", | |
"react-router": "^2.0.0", | |
"redux": "^3.3.1" | |
}, | |
"devDependencies": { | |
"babel-core": "^6.5.2", | |
"babel-loader": "^6.2.2", | |
"babel-preset-es2015": "^6.5.0", | |
"babel-preset-react": "^6.5.0", | |
"babel-register": "^6.5.2", | |
"chai": "^3.5.0", | |
"enzyme": "^2.0.0", | |
"eslint": "^2.2.0", | |
"eslint-config-standard": "^5.1.0", | |
"eslint-config-standard-jsx": "^1.1.1", | |
"eslint-config-standard-react": "^2.3.0", | |
"eslint-loader": "^1.3.0", | |
"eslint-plugin-promise": "^1.0.8", | |
"eslint-plugin-react": "^4.1.0", | |
"eslint-plugin-standard": "^1.3.2", | |
"jsdom": "^8.0.4", | |
"json-loader": "^0.5.4", | |
"mocha": "^2.4.5", | |
"nyc": "^6.0.0", | |
"react-addons-test-utils": "^0.14.7", | |
"sinon": "^1.17.3", | |
"webpack": "^1.12.13" | |
} | |
} |
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
require("babel-register") | |
var express = require('express') | |
var React = require('react') | |
var ReactDOMServer = require('react-dom/server') | |
var ReactRouter = require('react-router') | |
var match = ReactRouter.match | |
var RouterContext = ReactRouter.RouterContext | |
var ReactRedux = require('react-redux') | |
var Provider = ReactRedux.Provider | |
var Layout = require('./js/Layout.jsx') | |
var Store = require('./js/Store.jsx') | |
var store = Store.store | |
var _ = require('lodash') | |
var fs = require('fs') | |
var port = 5050 | |
var baseTemplate = fs.readFileSync('./index.html') | |
var template = _.template(baseTemplate) | |
var ClientApp = require('./js/ClientApp.jsx') | |
var routes = ClientApp.Routes | |
var app = express() | |
app.use('/public', express.static('./public')) | |
app.use((req, res) => { | |
// Note that req.url here should be the full URL path from | |
// the original request, including the query string. | |
match({ routes: routes, location: req.url }, (error, redirectLocation, renderProps) => { | |
console.log(error, redirectLocation, renderProps) | |
if (error) { | |
res.status(500).send(error.message) | |
} else if (redirectLocation) { | |
res.redirect(302, redirectLocation.pathname + redirectLocation.search) | |
} else if (renderProps) { | |
// You can also check renderProps.components or renderProps.routes for | |
// your "not found" component or route respectively, and send a 404 as | |
// below, if you're using a catch-all route. | |
var body = ReactDOMServer.renderToString( | |
React.createElement(Provider,{store}, | |
React.createElement(Layout, {}, | |
React.createElement(RouterContext,renderProps) | |
) | |
) | |
) | |
res.status(200).send(template({body})) | |
} else { | |
res.status(404).send('Not found') | |
} | |
}) | |
}); | |
console.log('listening on ' + port) | |
app.listen(port) |
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
const React = require('react') | |
const Landing = require('./Landing') | |
const Search = require('./Search') | |
const Layout = require('./Layout') | |
const Details = require('./Details') | |
const ReactRouter = require('react-router') | |
const data = require('../public/data') | |
const { Router, Route, browserHistory, IndexRoute } = ReactRouter | |
const Store = require('./Store') | |
const { store } = Store | |
const reactRedux = require('react-redux') | |
const { Provider } = reactRedux | |
const shows = data.shows || [] | |
const routes = [ | |
<Route path='/' component={Landing} />, | |
<Route path='/search' component={Search} shows={shows} />, | |
<Route path='/details/:id' component={Details} /> | |
] | |
class App extends React.Component { | |
constructor (props) { | |
super(props) | |
this.assignShow = this.assignShow.bind(this) | |
} | |
assignShow (nextState, replace) { | |
const show = data.shows[nextState.params.id] | |
if (!show) { | |
return replace('/') | |
} | |
Object.assign(nextState.params, show) | |
return nextState | |
} | |
render () { | |
return ( | |
<Provider store={store}> | |
<Router history={browserHistory}> | |
<Route path='/' component={Layout}> | |
<IndexRoute component={Landing} /> | |
<Route path='/search' component={Search} shows={shows} /> | |
<Route path='/details/:id' component={Details} onEnter={this.assignShow} /> | |
</Route> | |
</Router> | |
</Provider> | |
) | |
} | |
} | |
App.Routes = routes | |
module.exports = App |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks. You are so smart. I guess that you think ES6 codes in server side is not easy to develop.