├── .gitignore ├── README.md ├── lessons ├── 00-setup │ ├── .babelrc │ ├── package.json │ ├── src │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ └── webpack.config.js ├── 01-router-route-link │ ├── App.js │ ├── index.html │ └── main.js ├── 02-hash-vs-browserHistory │ ├── App.js │ ├── index.html │ └── main.js ├── 03-activeStyle-ClassName │ ├── App.js │ ├── index.html │ └── main.js ├── 04-nested-routes │ ├── App.js │ ├── index.html │ └── main.js ├── 05-indexroute │ ├── App.js │ ├── index.html │ └── main.js ├── 06-route-parameters │ ├── App.js │ ├── index.html │ └── main.js ├── 07-named-components │ ├── App.js │ ├── index.html │ └── main.js ├── 08-query-params │ ├── App.js │ ├── index.html │ └── main.js ├── 09-redirect │ ├── App.js │ ├── index.html │ └── main.js ├── 10-routerWillLeave │ ├── App.js │ ├── index.html │ └── main.js ├── 11-animation │ ├── App.js │ ├── index.html │ └── main.js ├── index.html └── shared.css ├── package.json ├── server.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ```bash 2 | npm install 3 | npm start 4 | ``` 5 | 6 | open browser to http://localhost:3000 7 | -------------------------------------------------------------------------------- /lessons/00-setup/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /lessons/00-setup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router-setup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "react": "^0.14.7", 13 | "react-dom": "^0.14.7", 14 | "react-router": "^2.0.0" 15 | }, 16 | "devDependencies": { 17 | "babel-core": "^6.6.4", 18 | "babel-loader": "^6.2.4", 19 | "babel-preset-es2015": "^6.6.0", 20 | "babel-preset-react": "^6.5.0", 21 | "webpack": "^1.12.14", 22 | "webpack-dev-server": "^1.14.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lessons/00-setup/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const App = () =>

Hi world

4 | 5 | export default App; 6 | -------------------------------------------------------------------------------- /lessons/00-setup/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Router 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lessons/00-setup/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/00-setup/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/main.js', 3 | output: { 4 | path: './src', 5 | filename: 'bundle.js', 6 | }, 7 | devServer: { 8 | inline:true, 9 | contentBase: './src', 10 | port: 3333 11 | }, 12 | module: { 13 | loaders: [ 14 | { 15 | test: /\.js$/, 16 | exclude: /node_modules/, 17 | loader: 'babel' 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lessons/01-router-route-link/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | const Home = () =>

Home

; 5 | const About = () =>

About

; 6 | const Contact = () =>

Contact

; 7 | const Links = () => 8 | 13 | 14 | 15 | const App = () => { 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | ) 23 | }; 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /lessons/01-router-route-link/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Intro to Router, Route, Link 6 | 7 | 8 | 9 | <-- Lessons 10 |
11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lessons/01-router-route-link/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render( , document.getElementById( 'app' ) ); 5 | -------------------------------------------------------------------------------- /lessons/02-hash-vs-browserHistory/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, browserHistory } from 'react-router'; 3 | 4 | const Home = () =>

Home

; 5 | const About = () =>

About

; 6 | const Contact = () =>

Contact

; 7 | const Links = () => 8 | 13 | 14 | const App = () => { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | ) 22 | }; 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /lessons/02-hash-vs-browserHistory/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Intro to Router, Route, Link 6 | 7 | 8 | 9 | <-- Lessons 10 |
11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lessons/02-hash-vs-browserHistory/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render( , document.getElementById( 'app' ) ); 5 | -------------------------------------------------------------------------------- /lessons/03-activeStyle-ClassName/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | const Home = () =>

Home

; 5 | const About = () =>

About

; 6 | const Contact = () =>

Contact

; 7 | 8 | const Links = () => 9 | 14 | 15 | const App = () => { 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | ) 23 | }; 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /lessons/03-activeStyle-ClassName/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ActiveLinks 6 | 7 | 12 | 13 | 14 | <-- Lessons 15 |
16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lessons/03-activeStyle-ClassName/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render( , document.getElementById( 'app' ) ); 5 | -------------------------------------------------------------------------------- /lessons/04-nested-routes/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | const Home = ( props ) =>

Home

{props.children}
; 5 | const About = ( props ) =>

About

{props.children}
; 6 | const Contact = () =>

Contact

; 7 | const Links = () => 8 | 14 | 15 | const App = () => { 16 | return ( 17 | 18 | 19 | 20 | {/* */} 21 | 22 | 23 | 24 | 25 | ) 26 | }; 27 | 28 | export default App; 29 | 30 | -------------------------------------------------------------------------------- /lessons/04-nested-routes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Basic Nested Routes 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/04-nested-routes/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/05-indexroute/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, IndexRoute, hashHistory } from 'react-router'; 3 | 4 | const Outer = (props) =>

Our Site

{props.children}
; 5 | const About = () =>

About

; 6 | const Contact = () =>

Contact

; 7 | 8 | 9 | const Links = () => 10 | 15 | 16 | 17 | class App extends React.Component { 18 | render(){ 19 | return ( 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | } 29 | } 30 | 31 | export default App; 32 | -------------------------------------------------------------------------------- /lessons/05-indexroute/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IndexRoute & IndexLink 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/05-indexroute/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/06-route-parameters/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | const Message = (props) => 5 |

{props.params.message || 'Hello'}

6 | 7 | const Links = () => 8 | 13 | 14 | 15 | class App extends React.Component { 16 | render(){ 17 | return ( 18 | 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /lessons/06-route-parameters/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Basic Route Parameters 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/06-route-parameters/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/07-named-components/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, IndexRoute, hashHistory } from 'react-router'; 3 | 4 | const Home = () =>

Home

5 | const HomeBody = () =>
this is the home body
6 | const Other = () =>

Other

7 | const OtherBody = () =>
this is the Other body
8 | 9 | const Container = (props) => 10 |
{props.header}{props.body}
11 | 12 | const Links = () => 13 | 17 | 18 | class App extends React.Component { 19 | render(){ 20 | return ( 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | } 29 | } 30 | 31 | export default App; 32 | -------------------------------------------------------------------------------- /lessons/07-named-components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Named Components 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/07-named-components/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/08-query-params/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | const Page = (props) => 5 |

{props.location.query.message || 'Hello'}

6 | 7 | const Links = () => 8 | 11 | 12 | class App extends React.Component { 13 | render(){ 14 | return ( 15 | 16 | 17 | 18 | ) 19 | } 20 | } 21 | 22 | export default App; 23 | -------------------------------------------------------------------------------- /lessons/08-query-params/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | query params 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/08-query-params/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/09-redirect/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Router, 4 | Route, 5 | Link, 6 | IndexRoute, 7 | Redirect, 8 | hashHistory 9 | } from 'react-router'; 10 | 11 | const Home = () =>

Home

12 | const NewPage = (props) =>

New Page {props.params.id}

13 | const Container = (props) =>
{props.children}
14 | 15 | const Links = () => 16 | 21 | 22 | class App extends React.Component { 23 | render(){ 24 | return ( 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ) 33 | } 34 | } 35 | 36 | export default App; 37 | -------------------------------------------------------------------------------- /lessons/09-redirect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redirect 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/09-redirect/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/10-routerWillLeave/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link, hashHistory } from 'react-router'; 3 | 4 | // const Home = () =>

Home

; 5 | 6 | class Home extends React.Component { 7 | componentWillMount(){ 8 | this.context.router.setRouteLeaveHook( 9 | this.props.route, 10 | this.routerWillLeave 11 | ) 12 | } 13 | 14 | routerWillLeave( nextLocation ){ 15 | return `leaving home for ${nextLocation.pathname}` 16 | } 17 | 18 | render(){ 19 | return

Home

; 20 | } 21 | } 22 | 23 | Home.contextTypes = { router: React.PropTypes.object.isRequired } 24 | 25 | const About = () =>

About

; 26 | const Links = () => { 27 | return ( 28 | 32 | ) 33 | }; 34 | 35 | const App = () => { 36 | return ( 37 | 38 | 39 | 40 | 41 | ) 42 | }; 43 | 44 | export default App; 45 | -------------------------------------------------------------------------------- /lessons/10-routerWillLeave/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Confirming Navigation 6 | 7 | 8 | 9 | <-- Lessons
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lessons/10-routerWillLeave/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/11-animation/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 3 | import { Router, Route, Link, IndexRoute, hashHistory } from 'react-router'; 4 | 5 | const Page1 = () => { 6 | return ( 7 |
8 | Go to Page 2 9 |
10 | ) 11 | }; 12 | 13 | const Page2 = () => { 14 | return ( 15 |
16 | Go to Page 1 17 |
18 | ) 19 | }; 20 | 21 | class Container extends React.Component { 22 | render() { 23 | var child = React.cloneElement( React.Children.only( this.props.children ), { 24 | key: Math.random() 25 | }); 26 | return ( 27 | 30 | { child } 31 | 32 | ) 33 | } 34 | } 35 | 36 | const App =() => { 37 | return ( 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ) 46 | }; 47 | 48 | export default App; 49 | -------------------------------------------------------------------------------- /lessons/11-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Animation 6 | 7 | 51 | 52 | 53 | <-- Lessons 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /lessons/11-animation/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('app')); 5 | -------------------------------------------------------------------------------- /lessons/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Router 6 | 7 | 8 |
    9 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /lessons/shared.css: -------------------------------------------------------------------------------- 1 | nav a { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egghead-react-router", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "author": "", 7 | "license": "ISC", 8 | "dependencies": { 9 | "history": "^1.13.1", 10 | "react": "^0.14.3", 11 | "react-addons-css-transition-group": "^0.14.3", 12 | "react-dom": "^0.14.3", 13 | "react-router": "^2.0.0" 14 | }, 15 | "devDependencies": { 16 | "babel-core": "^6.2.1", 17 | "babel-loader": "^6.2.0", 18 | "babel-preset-es2015": "^6.1.18", 19 | "babel-preset-react": "^6.1.18", 20 | "express": "^4.13.3", 21 | "express-urlrewrite": "^1.2.0", 22 | "webpack": "^1.12.9", 23 | "webpack-dev-middleware": "^1.3.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | var rewrite = require('express-urlrewrite') 3 | var webpack = require('webpack') 4 | var webpackDevMiddleware = require('webpack-dev-middleware') 5 | var WebpackConfig = require('./webpack.config') 6 | 7 | var app = express() 8 | 9 | app.use(webpackDevMiddleware(webpack(WebpackConfig), { 10 | publicPath: '/build/', 11 | stats: { 12 | colors: true 13 | } 14 | })) 15 | 16 | var fs = require('fs') 17 | var path = require('path') 18 | var lessonDir = __dirname + '/lessons' 19 | 20 | 21 | fs.readdirSync(lessonDir).forEach(function (file) { 22 | if (fs.statSync(path.join(lessonDir, file)).isDirectory()) 23 | app.use(rewrite('/' + file + '/*', '/' + file + '/index.html')) 24 | }) 25 | 26 | app.use(express.static(lessonDir)) 27 | 28 | app.listen(3000, function(){ 29 | console.log('App running at http://localhost:3000') 30 | }) 31 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | var webpack = require('webpack') 4 | var lessonsDir = __dirname + '/lessons' 5 | 6 | 7 | function getLessons(){ 8 | var entries = {} 9 | fs.readdirSync(lessonsDir).forEach(function(dir){ 10 | if(fs.statSync(path.join(lessonsDir, dir)).isDirectory()){ 11 | if(dir !== '00-setup'){ 12 | entries[dir.substring(3)] = path.join(lessonsDir, dir, 'main.js'); 13 | } 14 | } 15 | }); 16 | return entries 17 | } 18 | 19 | 20 | module.exports = { 21 | 22 | devtool: 'inline-source-map', 23 | 24 | entry: getLessons(), 25 | 26 | output: { 27 | path: lessonsDir + '/build', 28 | filename: '[name].js', 29 | publicPath: '/build/' 30 | }, 31 | 32 | module: { 33 | loaders: [ 34 | { 35 | test: /\.jsx?$/, 36 | exclude: /(node_modules|bower_components)/, 37 | loader: 'babel', 38 | query: { 39 | presets: ['es2015', 'react'] 40 | } 41 | } 42 | ] 43 | }, 44 | 45 | plugins: [ 46 | new webpack.optimize.CommonsChunkPlugin('shared.js') 47 | ] 48 | 49 | } 50 | --------------------------------------------------------------------------------