Skip to content

Commit 4c0e6b0

Browse files
committed
Add route configuration guide
1 parent ec471f8 commit 4c0e6b0

File tree

4 files changed

+173
-10
lines changed

4 files changed

+173
-10
lines changed

docs/GettingStarted.md

Whitespace-only changes.

docs/Introduction.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ We'd have to make our URL parsing a lot smarter, and we would end up with a lot
9797
Let's refactor our app to use React Router.
9898

9999
```js
100-
// first we import some components
100+
// First we import some components...
101101
import { Router, Route, Link } from 'react-router';
102102

103-
// then we delete a bunch of code from `App` and add some `Link`
104-
// components
103+
// Then we delete a bunch of code from App and
104+
// add some <Link> elements...
105105
var App = React.createClass({
106106
render() {
107107
return (
@@ -123,7 +123,7 @@ var App = React.createClass({
123123
}
124124
});
125125

126-
// Finally we render a Router component with some Routes.
126+
// Finally, we render a <Router> with some <Route>s.
127127
// It does all the fancy routing stuff for us.
128128
React.render((
129129
<Router>
@@ -135,7 +135,7 @@ React.render((
135135
), document.body);
136136
```
137137

138-
React Router knows how to build nested UI for us, so we don't have to manually figure out which `<Child>` component to render. If you're not digging the JSX route config you can use plain objects instead:
138+
React Router knows how to build nested UI for us, so we don't have to manually figure out which `<Child>` component to render. Internally, the router converts your `<Route>` element hierarchy to a [route config](Glossary.md#routeconfig). But if you're not digging the JSX you can use plain objects instead:
139139

140140
```js
141141
var routes = {
@@ -150,7 +150,7 @@ var routes = {
150150
React.render(<Router routes={routes} />, document.body);
151151
```
152152

153-
### Adding more UI
153+
### Adding More UI
154154

155155
Alright, now we're ready to nest the inbox messages inside the inbox UI.
156156

@@ -177,10 +177,10 @@ var Inbox = React.createClass({
177177
React.render((
178178
<Router>
179179
<Route path="/" component={App}>
180-
<Route path="about" component={About}/>
180+
<Route path="about" component={About} />
181181
<Route path="inbox" component={Inbox}>
182182
{/* Add the route, nested where we want the UI to nest */}
183-
<Route path="messages/:id" component={Message}/>
183+
<Route path="messages/:id" component={Message} />
184184
</Route>
185185
</Route>
186186
</Router>
@@ -189,7 +189,7 @@ React.render((
189189

190190
Now visits to URLs like `inbox/messages/Jkei3c32` will match the new route and nest the UI branch of `App -> Inbox -> Message`.
191191

192-
### Getting URL parameters
192+
### Getting URL Parameters
193193

194194
We're going to need to know something about the message in order to fetch it from the server. Route components get some useful properties injected into them when you render, particularly the parameters from the dynamic segment of your path. In our case, `:id`.
195195

@@ -211,3 +211,5 @@ var Message = React.createClass({
211211
```
212212

213213
That's the gist of React Router. Application UIs are boxes inside of boxes inside of boxes; now you can keep those boxes in sync with the URL and link to them easily.
214+
215+
The docs about [route configuration](RouteConfiguration.md) describe more of the router's features in depth.

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## Table of Contents
22

33
- [Introduction](Introduction.md)
4-
- [Getting Started](GettingStarted.md)
4+
- [Route Configuration](RouteConfiguration.md)
55
- [Dynamic Routing](DynamicRouting.md)
66
- [Advanced Usage](AdvancedUsage.md)
77
- [Server Rendering](ServerRendering.md)

docs/RouteConfiguration.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
## Route Configuration
2+
3+
Let's start with the simple app from [the introduction](Introduction.md).
4+
5+
```js
6+
import React from 'react';
7+
import { Router, Route } from 'react-router';
8+
9+
var App = React.createClass({
10+
render() {
11+
return (
12+
<div>
13+
<h1>App</h1>
14+
<ul>
15+
<li><Link to="/about">About</Link></li>
16+
<li><Link to="/inbox">Inbox</Link></li>
17+
</ul>
18+
{this.props.children}
19+
</div>
20+
)
21+
}
22+
});
23+
24+
var About = React.createClass({
25+
render() {
26+
return <h3>About</h3>;
27+
}
28+
});
29+
30+
var Inbox = React.createClass({
31+
render() {
32+
return (
33+
<div>
34+
<h2>Inbox</h2>
35+
{this.props.children || "Welcome to your Inbox"}
36+
</div>
37+
);
38+
}
39+
});
40+
41+
var Message = React.createClass({
42+
render() {
43+
return <h3>Message {this.props.params.id}</h3>;
44+
}
45+
});
46+
47+
React.render((
48+
<Router>
49+
<Route path="/" component={App}>
50+
<Route path="about" component={About} />
51+
<Route path="inbox" component={Inbox}>
52+
<Route path="messages/:id" component={Message} />
53+
</Route>
54+
</Route>
55+
</Router>
56+
), document.body);
57+
```
58+
59+
As configured, this app knows how to render the following 4 URLs:
60+
61+
URL | Components
62+
------------------------|-----------
63+
`/` | `App`
64+
`/about` | `App -> About`
65+
`/inbox` | `App -> Inbox`
66+
`/inbox/messages/:id` | `App -> Inbox -> Message`
67+
68+
### Adding an Index
69+
70+
Imagine we'd like to render another component inside of `App` when the URL is `/`. Currently, `this.props.children` is `undefined` in this case. We can use an `<IndexRoute>` for that.
71+
72+
```js
73+
import { IndexRoute } from 'react-router';
74+
75+
var Dashboard = React.createClass({
76+
render() {
77+
return <div>Welcome to the app!</div>;
78+
}
79+
});
80+
81+
React.render((
82+
<Router>
83+
<Route path="/" component={App}>
84+
{/* Show the dashboard at / */}
85+
<IndexRoute component={Dashboard} />
86+
<Route path="about" component={About} />
87+
<Route path="inbox" component={Inbox}>
88+
<Route path="messages/:id" component={Message} />
89+
</Route>
90+
</Route>
91+
</Router>
92+
), document.body);
93+
```
94+
95+
Now, `this.props.children` will be a `<Dashboard>` element inside `App`'s `render` method! This functionality is similar to Apache's [`DirectoryIndex`](http://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex) or nginx's [`index`](http://nginx.org/en/docs/http/ngx_http_index_module.html#index) directive.
96+
97+
Our sitemap now looks like this:
98+
99+
URL | Components
100+
------------------------|-----------
101+
`/` | `App -> Dashboard`
102+
`/about` | `App -> About`
103+
`/inbox` | `App -> Inbox`
104+
`/inbox/messages/:id` | `App -> Inbox -> Message`
105+
106+
### Decoupling the UI from the URL
107+
108+
It would be nice if we could remove the `/inbox` segment from the `/inbox/messages/:id` URL, but still render `Message` nested inside the `App -> Inbox` UI. We can use an absolute path for that.
109+
110+
```js
111+
React.render((
112+
<Router>
113+
<Route path="/" component={App}>
114+
<IndexRoute component={Dashboard} />
115+
<Route path="about" component={About} />
116+
<Route path="inbox" component={Inbox}>
117+
{/* Use /messages/:id instead of messages/:id */}
118+
<Route path="/messages/:id" component={Message} />
119+
</Route>
120+
</Route>
121+
</Router>
122+
), document.body);
123+
```
124+
125+
We can now render the following URLs:
126+
127+
URL | Components
128+
------------------------|-----------
129+
`/` | `App -> Dashboard`
130+
`/about` | `App -> About`
131+
`/inbox` | `App -> Inbox`
132+
`/messages/:id` | `App -> Inbox -> Message`
133+
134+
The ability to use absolute paths in deeply nested routes gives us complete control over what the URL looks like! We don't have to add more segments to the URL just to get nested UI.
135+
136+
### Preserving URLs
137+
138+
But wait just a minute ... we just changed a URL! [That's not cool](http://www.w3.org/Provider/Style/URI.html). Now everyone who had a link to `/inbox/messages/5` has a **broken link**. :(
139+
140+
Not to worry. Redirects to the rescue!
141+
142+
```js
143+
import { Redirect } from 'react-router';
144+
145+
React.render((
146+
<Router>
147+
<Route path="/" component={App}>
148+
<IndexRoute component={Dashboard} />
149+
<Route path="about" component={About} />
150+
<Route path="inbox" component={Inbox}>
151+
<Route path="/messages/:id" component={Message} />
152+
153+
{/* Redirect /inbox/messages/:id to /messages/:id */}
154+
<Redirect from="messages/:id" to="/messages/:id" />
155+
</Route>
156+
</Route>
157+
</Router>
158+
), document.body);
159+
```
160+
161+
Now when someone clicks on that link to `/inbox/messages/5` they'll automatically be redirected to `/messages/5`. We don't hate our users anymore! :highfive:

0 commit comments

Comments
 (0)