Skip to content
This repository was archived by the owner on Jul 19, 2019. It is now read-only.

Commit 50f7f54

Browse files
committed
Add in lessons
1 parent f9f476f commit 50f7f54

17 files changed

+1251
-1
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bundle.js
2+
*.bundle.js

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
React Router Tutorial
2+
=====================
3+
4+
Quick lessons for getting up-to-speed with React Router.
5+
6+
See [01-setting-up.md](/lessons/01-setting-up.md) to get started.
7+
8+
Each lesson has a commit for the final code so you can `git checkout
9+
<previous lesson final sha>` before starting a new one if you'd like.
10+
11+
Missing stuff that will come eventually, hopefully ... maybe.
12+
13+
1. an app that isn't completely pointless
14+
- egghead.io videos
15+
- code splitting
16+
- location state
17+
- data integration
18+

lessons/01-setting-up.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Setting up the Project
2+
3+
First you'll need [Node.js](https://nodejs.org) and the package manager
4+
that comes with it: [npm](https://www.npmjs.com/).
5+
6+
Once you've got that working, head to the command line where we'll set
7+
up our project.
8+
9+
## Clone the Tutorial
10+
11+
```
12+
git clone <tutorial url>
13+
cd react-router-tutorial
14+
git checkout start
15+
npm start
16+
```
17+
18+
Now open up http://localhost:8080
19+
20+
Feel free to poke around the code to see how we're using webpack and npm
21+
scripts to run the app.
22+
23+
You should see a "Hello React Router" message in the browser.
24+
25+
## Make Some Changes
26+
27+
Open up `modules/App.js` and change the text to something like "Hello
28+
<your name>". The browser automatically reloads with your new code.
29+
30+
---
31+
32+
[Next: Rendering a Router](02-rendering-a-router.md)
33+

lessons/02-rendering-a-router.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Rendering a Router
2+
3+
At its heart, React Router is a component.
4+
5+
```js
6+
render(<Router/>, document.getElementById('app'))
7+
```
8+
9+
That's not going display anything until we configure a route.
10+
11+
Open up `index.js` and
12+
13+
1. import `Router` and `Route`
14+
2. render a `Router` instead of `App`
15+
16+
```js
17+
// ...
18+
import { Router, Route, hashHistory } from 'react-router'
19+
20+
render((
21+
<Router history={hashHistory}>
22+
<Route path="/" component={App}/>
23+
</Router>
24+
), document.getElementById('app'))
25+
```
26+
27+
Make sure your server is running with `npm start` and then visit
28+
http://localhost:8080
29+
30+
You should get the same screen as before, but this time with some junk
31+
in the URL. We're using `hashHistory`--it manages the routing history
32+
with the hash portion of the url. It's got that extra junk to shim some
33+
behavior the browser has natively when using real urls. We'll change
34+
this to use real urls later and lose the junk, but for now, this works
35+
great because it doesn't require any server-side configuration.
36+
37+
## Adding More Screens
38+
39+
Create two new components at:
40+
41+
- `modules/About.js`
42+
- `modules/Repos.js`
43+
44+
```js
45+
// modules/About.js
46+
import React from 'react'
47+
48+
export default React.createClass({
49+
render() {
50+
return <div>About</div>
51+
}
52+
})
53+
```
54+
55+
```js
56+
// modules/Repos.js
57+
import React from 'react'
58+
59+
export default React.createClass({
60+
render() {
61+
return <div>Repos</div>
62+
}
63+
})
64+
```
65+
66+
Now we can couple them to the app at their respective paths.
67+
68+
```js
69+
import About from './modules/About'
70+
import Repos from './modules/Repos'
71+
72+
render((
73+
<Router history={hashHistory}>
74+
<Route path="/" component={App}/>
75+
{/* add the routes here */}
76+
<Route path="/repos" component={Repos}/>
77+
<Route path="/about" component={About}/>
78+
</Router>
79+
), document.getElementById('app'))
80+
```
81+
82+
Now visit http://localhost:8080/#/about and
83+
http://localhost:8080/#/repos
84+
85+
---
86+
87+
[Next: Navigating With Link](03-navigating-with-link.md)
88+

lessons/03-navigating-with-link.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Navigating with Link
2+
3+
Perhaps the most used component in your app is `Link`. Its almost
4+
identical to the `<a/>` tag you're used to except that its aware of
5+
the `Router` it was rendered in.
6+
7+
Lets create some navigation in our `App` component.
8+
9+
```js
10+
// modules/App.js
11+
import { Link } from 'react-router'
12+
13+
export default React.createClass({
14+
render() {
15+
return (
16+
<div>
17+
<h1>React Router Tutorial</h1>
18+
<ul role="nav">
19+
<li><Link to="/about">About</Link></li>
20+
<li><Link to="/repos">Repos</Link></li>
21+
</ul>
22+
</div>
23+
)
24+
}
25+
})
26+
```
27+
28+
Now visit http://localhost:8080/ and click the links, click back, click
29+
forward. It works!
30+
31+
---
32+
33+
[Next: Nested Routes](04-nested-routes.md)
34+

lessons/04-nested-routes.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Nested Routes
2+
3+
The navigation we added to `App` should probably be present on every
4+
screen. Without React Router, we could wrap that `ul` into a
5+
component, say `Nav`, and render a `Nav` on every one of our screens.
6+
7+
This approach isn't as clean as the application grows. React Router
8+
provides another way to share UI like this with nested routes, a trick
9+
it learned from [Ember](http://emberjs.com) (/me tips hat).
10+
11+
## Nested UI and Nested URLs
12+
13+
Have you ever noticed your app is just a series of boxes inside boxes
14+
inside boxes? Have you also noticed your URLs tend to be coupled to that
15+
nesting? For example given this url, `/repos/123`, our
16+
components would probably look like this:
17+
18+
```js
19+
<App> {/* / */}
20+
<Repos> {/* /repos */}
21+
<Repo/> {/* /repos/123 */}
22+
</Repos>
23+
</App>
24+
```
25+
26+
And our UI something like:
27+
28+
```
29+
+-------------------------------------+
30+
| Home Repos About | <- App
31+
+------+------------------------------+
32+
| | |
33+
Repos -> | repo | Repo 1 |
34+
| | |
35+
| repo | Boxes inside boxes |
36+
| | inside boxes ... | <- Repo
37+
| repo | |
38+
| | |
39+
| repo | |
40+
| | |
41+
+------+------------------------------+
42+
```
43+
44+
React Router embraces this by letting you nest your routes, which
45+
automatically becomes nested UI.
46+
47+
## Sharing Our Navigation
48+
49+
Lets nest our `About` and `Repos` components inside of `App` so that we
50+
can share the navigation with all screens in the app. We do it in two
51+
steps:
52+
53+
First, let the `App` `Route` have children, and move the other routes
54+
underneath it.
55+
56+
```js
57+
// index.js
58+
// ...
59+
render((
60+
<Router history={hashHistory}>
61+
<Route path="/" component={App}>
62+
{/* make them children of `App` */}
63+
<Route path="/repos" component={Repos}/>
64+
<Route path="/about" component={About}/>
65+
</Route>
66+
</Router>
67+
), document.getElementById('app'))
68+
```
69+
70+
Next, render children inside of `App`.
71+
72+
```js
73+
// modules/App.js
74+
// ...
75+
render() {
76+
return (
77+
<div>
78+
<h1>Ghettohub Issues</h1>
79+
<ul role="nav">
80+
<li><Link to="/about">About</Link></li>
81+
<li><Link to="/repos">Repos</Link></li>
82+
</ul>
83+
84+
{/* add this */}
85+
{this.props.children}
86+
87+
</div>
88+
)
89+
}
90+
// ...
91+
```
92+
93+
Alright, now go click the links and notice that the `App` component
94+
continues to render while the child route's component gets swapped
95+
around as `this.props.children` :)
96+
97+
React Router is constructing your UI like this:
98+
99+
```js
100+
// at /about
101+
<App>
102+
<About/>
103+
</App>
104+
105+
// at /repos
106+
<App>
107+
<Repos/>
108+
</App>
109+
```
110+
111+
## By Small and Simple Things are Great Things Brought to Pass
112+
113+
The best way to build large things is to stitch small things together.
114+
115+
This is the real power of React Router, every route can be developed
116+
(even rendered!) as an independent application. Your route configuration
117+
stitches all these apps together however you'd like. Applications
118+
inside of Applications, boxes inside of boxes.
119+
120+
What happens if you move the `About` route outside of `App`?
121+
122+
Okay, now put it back.
123+
124+
---
125+
126+
[Next: Active Links](05-active-links.md)

lessons/05-active-links.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Active Links
2+
3+
One way that `Link` is different from `a` is that it knows if the path
4+
it links to is active so you can style it differently.
5+
6+
## Active Styles
7+
8+
Let's see how it looks with inline styles, add `activeStyle` to your
9+
`Links`s.
10+
11+
```js
12+
// modules/App.js
13+
<li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>
14+
<li><Link to="/repos" activeStyle={{ color: 'red' }}>Repos</Link></li>
15+
```
16+
17+
How as you navigate, the active link is red.
18+
19+
## Active Class Name
20+
21+
You can also use an active class name instead of inline-styles.
22+
23+
```js
24+
<li><Link to="/about" activeClassName="active">About</Link></li>
25+
<li><Link to="/repos" activeClassName="active">Repos</Link></li>
26+
```
27+
28+
We don't have a stylesheet on the page yet though. Lets add one--extra
29+
points if you can add a `link` tag from memory. Double extra points if
30+
you can leave the attributes unquoted, against your better judgement.
31+
32+
```html
33+
<link rel=stylesheet href=index.css />
34+
```
35+
36+
And the css file:
37+
38+
```css
39+
.active {
40+
color: green;
41+
}
42+
```
43+
44+
You'll need to manually refresh the browser since Webpack isn't building
45+
our `index.html`.
46+
47+
## Nav Link Wrappers
48+
49+
Most links in your site don't need to know they are active, usually just
50+
primary navigation links need to know. Its useful to wrap those so you
51+
don't have to remember what your `activeClassName` or `activeStyle` is
52+
everywhere.
53+
54+
Create a new file at `modules/NavLink.js` that looks like this:
55+
56+
```js
57+
// modules/NavLink.js
58+
import React from 'react'
59+
import { Link } from 'react-router'
60+
61+
export default React.createClass({
62+
render() {
63+
return <Link {...this.props} activeClassName="active"/>
64+
}
65+
})
66+
```
67+
68+
Now you can go change your links to `NavLink`s.
69+
70+
```js
71+
// App.js
72+
import NavLink from './NavLink'
73+
74+
// ...
75+
76+
<li><NavLink to="/about">About</NavLink></li>
77+
<li><NavLink to="/repos">Repos</NavLink></li>
78+
```
79+
80+
Oh, how beautiful upon the renders is the composability of components.
81+
82+
---
83+
84+
[Next: Params](06-params.md)
85+

0 commit comments

Comments
 (0)