├── .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 |
--------------------------------------------------------------------------------