From 5dfb73bd8fb5430f0be6d2ff0883aa9c06ae321a Mon Sep 17 00:00:00 2001 From: Dennis Ting Date: Fri, 28 Oct 2016 01:18:52 -0700 Subject: [PATCH] POC react router 4 --- package.json | 4 +-- src/client/Root.js | 9 ++++--- src/components/App/index.js | 17 ++++++------ src/components/App/routes.js | 14 ++++++++++ src/components/NoMatch/index.js | 10 +++++++ src/routes/index.js | 40 ---------------------------- src/server/index.js | 47 ++++++++++++++++++--------------- 7 files changed, 66 insertions(+), 75 deletions(-) create mode 100644 src/components/App/routes.js create mode 100644 src/components/NoMatch/index.js delete mode 100644 src/routes/index.js diff --git a/package.json b/package.json index 0c7a1fe..c244060 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "homepage": "https://github.com/nytm/wf-kyt-starter-universal#readme", "kyt": { - "version": "^0.2.0" + "version": "^0.3.0" }, "dependencies": { "compression": "^1.6.2", @@ -25,6 +25,6 @@ "react": "^15.3.0", "react-addons-test-utils": "^15.3.0", "react-dom": "^15.3.0", - "react-router": "^2.6.1" + "react-router": "^4.0.0-alpha.5" } } diff --git a/src/client/Root.js b/src/client/Root.js index 85f4735..49d6785 100644 --- a/src/client/Root.js +++ b/src/client/Root.js @@ -1,13 +1,14 @@ import React from 'react'; -import Router from 'react-router/lib/Router'; -import browserHistory from 'react-router/lib/browserHistory'; -import routes from '../routes'; +import { BrowserRouter } from 'react-router'; +import App from '../components/App'; // We need a Root component for React Hot Loading. function Root() { return ( - + + + ); } diff --git a/src/components/App/index.js b/src/components/App/index.js index 5f8277e..3e34644 100644 --- a/src/components/App/index.js +++ b/src/components/App/index.js @@ -1,9 +1,11 @@ -import React, { PropTypes } from 'react'; -import Link from 'react-router/lib/Link'; +import React from 'react'; +import { Link, Match, Miss } from 'react-router'; +import NoMatch from '../NoMatch'; import styles from './styles.scss'; +import routes from './routes'; -function App({ children }) { +function App() { return (
@@ -16,14 +18,13 @@ function App({ children }) {
- {children} + {routes.map((route, i) => ( + + ))} +
); } -App.propTypes = { - children: PropTypes.node, -}; - export default App; diff --git a/src/components/App/routes.js b/src/components/App/routes.js new file mode 100644 index 0000000..5270766 --- /dev/null +++ b/src/components/App/routes.js @@ -0,0 +1,14 @@ + +import Home from '../Home'; +import Tools from '../Tools'; + +const routes = [{ + exactly: true, + pattern: '/', + component: Home, +}, { + pattern: '/tools', + component: Tools, +}]; + +export default routes; diff --git a/src/components/NoMatch/index.js b/src/components/NoMatch/index.js new file mode 100644 index 0000000..70a4162 --- /dev/null +++ b/src/components/NoMatch/index.js @@ -0,0 +1,10 @@ + +import React from 'react'; + +function NoMatch() { + return ( +

No match for {location.pathname}

+ ); +} + +export default NotMatch; diff --git a/src/routes/index.js b/src/routes/index.js deleted file mode 100644 index ccf3e95..0000000 --- a/src/routes/index.js +++ /dev/null @@ -1,40 +0,0 @@ - -import React from 'react'; -import Route from 'react-router/lib/Route'; -import IndexRoute from 'react-router/lib/IndexRoute'; -import App from '../components/App'; - -// Webpack 2 supports ES2015 `System.import` by auto- -// chunking assets. Check out the following for more: -// https://gist.github.com/sokra/27b24881210b56bbaff7#code-splitting-with-es6 - -const importHome = (nextState, cb) => { - System.import('../components/Home') - .then(module => cb(null, module.default)) - .catch((e) => { throw e; }); -}; - -const importTools = (nextState, cb) => { - System.import('../components/Tools') - .then(module => cb(null, module.default)) - .catch((e) => { throw e; }); -}; - -// We use `getComponent` to dynamically load routes. -// https://github.com/reactjs/react-router/blob/master/docs/guides/DynamicRouting.md -const routes = ( - - - - -); - -// Unfortunately, HMR breaks when we dynamically resolve -// routes so we need to require them here as a workaround. -// https://github.com/gaearon/react-hot-loader/issues/288 -if (module.hot) { - require('../components/Home'); // eslint-disable-line global-require - require('../components/Tools'); // eslint-disable-line global-require -} - -export default routes; diff --git a/src/server/index.js b/src/server/index.js index 431df76..7663dd4 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -4,11 +4,9 @@ import compression from 'compression'; import path from 'path'; import React from 'react'; import { renderToString } from 'react-dom/server'; -import RouterContext from 'react-router/lib/RouterContext'; -import createMemoryHistory from 'react-router/lib/createMemoryHistory'; -import match from 'react-router/lib/match'; +import { ServerRouter, createServerRenderContext } from 'react-router'; +import App from '../components/App'; import template from './template'; -import routes from '../routes'; const clientAssets = require(KYT.ASSETS_MANIFEST); // eslint-disable-line import/no-dynamic-require const app = express(); @@ -24,25 +22,32 @@ app.use(express.static(path.join(process.cwd(), KYT.PUBLIC_DIR))); // Setup server side routing. app.get('*', (request, response) => { - const history = createMemoryHistory(request.originalUrl); - - match({ routes, history }, (error, redirectLocation, renderProps) => { - if (error) { - response.status(500).send(error.message); - } else if (redirectLocation) { - response.redirect(302, `${redirectLocation.pathname}${redirectLocation.search}`); - } else if (renderProps) { - // When a React Router route is matched then we render - // the components and assets into the template. - response.status(200).send(template({ - root: renderToString(), - jsBundle: clientAssets.main.js, - cssBundle: clientAssets.main.css, - })); + const context = createServerRenderContext(); + let markup = renderToString( + + + + ); + const result = context.getResult(); + if (result.redirect) { + response.redirect(302, `${result.redirect.pathname}${result.redirect.search}`); + } else { + if (result.missed) { + response.status(404); + markup = renderToString( + + + + ); } else { - response.status(404).send('Not found'); + response.status(200); } - }); + response.send(template({ + root: markup, + jsBundle: clientAssets.main.js, + cssBundle: clientAssets.main.css, + })); + } }); app.listen(parseInt(KYT.SERVER_PORT, 10));