Skip to content

Commit b13eeb8

Browse files
committed
ES6, react, and react-router updates lessons 13-14
1 parent a096d89 commit b13eeb8

29 files changed

+386
-172
lines changed

lessons/13-server-rendering/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["react", "es2015"]
3+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false

lessons/13-server-rendering/.eslintrc

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"extends": [
3+
"eslint:recommended",
4+
"plugin:import/errors",
5+
"plugin:import/warnings"
6+
],
7+
"plugins": [
8+
"react"
9+
],
10+
"parserOptions": {
11+
"ecmaVersion": 6,
12+
"sourceType": "module",
13+
"ecmaFeatures": {
14+
"jsx": true
15+
}
16+
},
17+
"env": {
18+
"es6": true,
19+
"browser": true,
20+
"node": true,
21+
"jquery": true,
22+
"mocha": true
23+
},
24+
"rules": {
25+
"quotes": 0,
26+
"no-console": 1,
27+
"no-debugger": 1,
28+
"no-var": 1,
29+
"indent": ["error", 2],
30+
"semi": [1, "always"],
31+
"no-trailing-spaces": 0,
32+
"eol-last": 0,
33+
"no-unused-vars": 0,
34+
"no-underscore-dangle": 0,
35+
"no-alert": 0,
36+
"no-lone-blocks": 0,
37+
"jsx-quotes": 1,
38+
"react/display-name": [ 1, {"ignoreTranspilerName": false }],
39+
"react/forbid-prop-types": [1, {"forbid": ["any"]}],
40+
"react/jsx-boolean-value": 1,
41+
"react/jsx-closing-bracket-location": 0,
42+
"react/jsx-curly-spacing": 1,
43+
"react/jsx-indent-props": 0,
44+
"react/jsx-key": 1,
45+
"react/jsx-max-props-per-line": 0,
46+
"react/jsx-no-bind": 1,
47+
"react/jsx-no-duplicate-props": 1,
48+
"react/jsx-no-literals": 0,
49+
"react/jsx-no-undef": 1,
50+
"react/jsx-pascal-case": 1,
51+
"react/jsx-sort-prop-types": 0,
52+
"react/jsx-sort-props": 0,
53+
"react/jsx-uses-react": 1,
54+
"react/jsx-uses-vars": 1,
55+
"react/no-danger": 1,
56+
"react/no-did-mount-set-state": 1,
57+
"react/no-did-update-set-state": 1,
58+
"react/no-direct-mutation-state": 1,
59+
"react/no-multi-comp": 1,
60+
"react/no-set-state": 0,
61+
"react/no-unknown-property": 1,
62+
"react/prefer-es6-class": 1,
63+
"react/prop-types": 1,
64+
"react/react-in-jsx-scope": 1,
65+
"react/require-extension": 1,
66+
"react/self-closing-comp": 1,
67+
"react/sort-comp": 1,
68+
"react/wrap-multilines": 1
69+
}
70+
}

lessons/13-server-rendering/README.md

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Alright, first things first. Server rendering, at its core is a simple
44
concept in React.
55

66
```js
7-
render(<App/>, domNode)
7+
render(<App/>, domNode);
88
// can be rendered on the server as
9-
const markup = renderToString(<App/>)
9+
const markup = renderToString(<App/>);
1010
```
1111

1212
It's not rocket science, but it also isn't trivial. First I'm going to
@@ -22,8 +22,8 @@ Make a new file called `webpack.server.config.js` and put this stuff in
2222
there:
2323

2424
```js
25-
var fs = require('fs')
26-
var path = require('path')
25+
var fs = require('fs');
26+
var path = require('path');
2727

2828
module.exports = {
2929

@@ -54,7 +54,7 @@ module.exports = {
5454
]
5555
}
5656

57-
}
57+
};
5858
```
5959

6060
Hopefully some of that makes sense, we aren't going to cover what all of
@@ -86,13 +86,13 @@ into it.
8686

8787
```js
8888
// modules/routes.js
89-
import React from 'react'
90-
import { Route, IndexRoute } from 'react-router'
91-
import App from './App'
92-
import About from './About'
93-
import Repos from './Repos'
94-
import Repo from './Repo'
95-
import Home from './Home'
89+
import React from 'react';
90+
import { Route, IndexRoute } from 'react-router';
91+
import App from './App';
92+
import About from './About';
93+
import Repos from './Repos';
94+
import Repo from './Repo';
95+
import Home from './Home';
9696

9797
module.exports = (
9898
<Route path="/" component={App}>
@@ -102,21 +102,21 @@ module.exports = (
102102
</Route>
103103
<Route path="/about" component={About}/>
104104
</Route>
105-
)
105+
);
106106
```
107107

108108
```js
109109
// index.js
110-
import React from 'react'
111-
import { render } from 'react-dom'
112-
import { Router, browserHistory } from 'react-router'
110+
import React from 'react';
111+
import { render } from 'react-dom';
112+
import { Router, browserHistory } from 'react-router';
113113
// import routes and pass them into <Router/>
114-
import routes from './modules/routes'
114+
import routes from './modules/routes';
115115

116116
render(
117117
<Router routes={routes} history={browserHistory}/>,
118118
document.getElementById('app')
119-
)
119+
);
120120
```
121121

122122
Now open up `server.js`. We're going to bring in two modules from React
@@ -138,12 +138,12 @@ we'll match the routes to the url, and finally render.
138138
```js
139139
// ...
140140
// import some new stuff
141-
import React from 'react'
141+
import React from 'react';
142142
// we'll use this to render our app to an html string
143-
import { renderToString } from 'react-dom/server'
143+
import { renderToString } from 'react-dom/server';
144144
// and these to match the url to routes and then render
145-
import { match, RouterContext } from 'react-router'
146-
import routes from './modules/routes'
145+
import { match, RouterContext } from 'react-router';
146+
import routes from './modules/routes';
147147

148148
// ...
149149

@@ -156,12 +156,12 @@ app.get('*', (req, res) => {
156156
// `props` in its state as it listens to `browserHistory`. But on the
157157
// server our app is stateless, so we need to use `match` to
158158
// get these props before rendering.
159-
const appHtml = renderToString(<RouterContext {...props}/>)
159+
const appHtml = renderToString(<RouterContext {...props}/>);
160160

161161
// dump the HTML into a template, lots of ways to do this, but none are
162162
// really influenced by React Router, so we're just using a little
163163
// function, `renderPage`
164-
res.send(renderPage(appHtml))
164+
res.send(renderPage(appHtml));
165165
})
166166
})
167167

@@ -177,10 +177,10 @@ function renderPage(appHtml) {
177177
`
178178
}
179179

180-
var PORT = process.env.PORT || 8080
180+
var PORT = process.env.PORT || 8080;
181181
app.listen(PORT, function() {
182182
console.log('Production Express server running at localhost:' + PORT)
183-
})
183+
});
184184
```
185185

186186
And that's it. Now if you run `NODE_ENV=production npm start` and visit
@@ -199,18 +199,18 @@ app.get('*', (req, res) => {
199199
// in here we can make some decisions all at once
200200
if (err) {
201201
// there was an error somewhere during route matching
202-
res.status(500).send(err.message)
202+
res.status(500).send(err.message);
203203
} else if (redirect) {
204204
// we haven't talked about `onEnter` hooks on routes, but before a
205205
// route is entered, it can redirect. Here we handle on the server.
206-
res.redirect(redirect.pathname + redirect.search)
206+
res.redirect(redirect.pathname + redirect.search);
207207
} else if (props) {
208208
// if we got props then we matched a route and can render
209-
const appHtml = renderToString(<RouterContext {...props}/>)
210-
res.send(renderPage(appHtml))
209+
const appHtml = renderToString(<RouterContext {...props}/>);
210+
res.send(renderPage(appHtml));
211211
} else {
212212
// no errors, no redirect, we just didn't match anything
213-
res.status(404).send('Not Found')
213+
res.status(404).send('Not Found');
214214
}
215215
})
216216
})

lessons/13-server-rendering/index.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import React from 'react'
2-
import { render } from 'react-dom'
3-
import { Router, Route, browserHistory, IndexRoute } from 'react-router'
4-
import App from './modules/App'
5-
import About from './modules/About'
6-
import Repos from './modules/Repos'
7-
import Repo from './modules/Repo'
8-
import Home from './modules/Home'
1+
import React from 'react';
2+
import { render } from 'react-dom';
3+
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
4+
import App from './modules/App';
5+
import About from './modules/About';
6+
import Repos from './modules/Repos';
7+
import Repo from './modules/Repo';
8+
import Home from './modules/Home';
99

1010
render((
1111
<Router history={browserHistory}>
@@ -17,4 +17,4 @@ render((
1717
<Route path="/about" component={About}/>
1818
</Route>
1919
</Router>
20-
), document.getElementById('app'))
20+
), document.getElementById('app'));
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React from 'react'
1+
import React from 'react';
22

3-
export default React.createClass({
3+
export default class About extends React.Component {
44
render() {
5-
return <div>About</div>
5+
return <div>About</div>;
66
}
7-
})
7+
}
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React from 'react'
2-
import NavLink from './NavLink'
1+
import React from 'react';
2+
import NavLink from './NavLink';
33

4-
export default React.createClass({
4+
class App extends React.Component {
55
render() {
66
return (
77
<div>
@@ -13,6 +13,10 @@ export default React.createClass({
1313
</ul>
1414
{this.props.children}
1515
</div>
16-
)
16+
);
1717
}
18-
})
18+
}
19+
20+
App.propTypes = {children: React.PropTypes.object};
21+
22+
export default App;
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React from 'react'
1+
import React from 'react';
22

3-
export default React.createClass({
3+
export default class Home extends React.Component {
44
render() {
5-
return <div>Home</div>
5+
return <div>Home</div>;
66
}
7-
})
7+
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// modules/NavLink.js
2-
import React from 'react'
3-
import { Link } from 'react-router'
2+
import React from 'react';
3+
import { Link } from 'react-router';
44

5-
export default React.createClass({
5+
export default class NavLink extends React.Component {
66
render() {
7-
return <Link {...this.props} activeClassName="active"/>
7+
return <Link {...this.props} activeClassName="active"/>;
88
}
9-
})
9+
}
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import React from 'react'
1+
import React from 'react';
22

3-
export default React.createClass({
3+
class Repo extends React.Component {
44
render() {
5-
const { userName, repoName } = this.props.params
5+
const { userName, repoName } = this.props.params;
66
return (
77
<div>
88
<h2>{userName} / {repoName}</h2>
99
</div>
10-
)
10+
);
1111
}
12-
})
12+
}
13+
14+
Repo.propTypes = {params: React.PropTypes.object};
15+
16+
export default Repo;
Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
import React from 'react'
2-
import NavLink from './NavLink'
1+
import React from 'react';
2+
import NavLink from './NavLink';
33

4-
export default React.createClass({
5-
contextTypes: {
6-
router: React.PropTypes.object
7-
},
4+
class Repos extends React.Component {
85

96
handleSubmit(event) {
10-
event.preventDefault()
11-
const userName = event.target.elements[0].value
12-
const repo = event.target.elements[1].value
13-
const path = `/repos/${userName}/${repo}`
14-
this.context.router.push(path)
15-
},
7+
event.preventDefault();
8+
const userName = event.target.elements[0].value;
9+
const repo = event.target.elements[1].value;
10+
const path = `/repos/${userName}/${repo}`;
11+
this.context.router.push(path);
12+
}
1613

1714
render() {
1815
return (
@@ -31,6 +28,16 @@ export default React.createClass({
3128
</ul>
3229
{this.props.children}
3330
</div>
34-
)
31+
);
3532
}
36-
})
33+
}
34+
35+
Repos.contextTypes = {
36+
router: React.PropTypes.object
37+
};
38+
39+
Repos.propTypes = {
40+
children: React.PropTypes.object
41+
};
42+
43+
export default Repos;

0 commit comments

Comments
 (0)