Skip to content

Commit ffabfc6

Browse files
committed
First commit of new docs
1 parent 63cb4ee commit ffabfc6

File tree

4 files changed

+343
-0
lines changed

4 files changed

+343
-0
lines changed

docs/GettingStarted.md

Whitespace-only changes.

docs/Glossary.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
## Glossary
2+
3+
This is a glossary of common terms used in the React Router codebase and documentation listed in alphabetical order, along with their [type signatures](http://flowtype.org/docs/quick-reference.html).
4+
5+
### Action
6+
7+
type Action = 'PUSH' | 'REPLACE' | 'POP';
8+
9+
An *action* describes the type of change to a URL. Possible values are:
10+
11+
- `PUSH` – indicates a new item was added to the history
12+
- `REPLACE` – indicates the current item in history was altered
13+
- `POP` – indicates there is a new current item, i.e. the "current pointer" changed
14+
15+
### Component
16+
17+
type Component = ReactClass | string;
18+
19+
A *component* is a React component class or a string (e.g. "div"). Basically, it's anything that can be used as the first argument to [`React.createElement`](https://facebook.github.io/react/docs/top-level-api.html#react.createelement).
20+
21+
### EnterHook
22+
23+
type EnterHook = (nextState: RoutingState, redirectTo: RedirectFunction, callback?: Function) => any;
24+
25+
An *enter hook* is a user-defined function that is called when a route is about to be rendered. It receives the next [routing state](#routingstate) as its first argument. The [`redirectTo` function](#redirectfunction) may be used to trigger a transition to a different URL.
26+
27+
If an enter hook needs to execute asynchronously, it may list a 3rd `callback` argument that it must call in order to cause the transition to proceed.
28+
29+
**Caution:** Using the `callback` in an enter hook causes the transition to wait until it is called. **This can lead to a non-responsive UI if you don't call it very quickly**.
30+
31+
### History
32+
33+
### LeaveHook
34+
35+
type LeaveHook = () => any;
36+
37+
A *leave hook* is a user-defined function that is called when a route is about to be unmounted.
38+
39+
### Location
40+
41+
type Location = {
42+
pathname: Pathname;
43+
search: QueryString;
44+
query: Query;
45+
state: any;
46+
action: Action;
47+
key: string;
48+
};
49+
50+
A *location* answers two important (philosophical) questions:
51+
52+
- Where am I?
53+
- How did I get here?
54+
55+
New locations are typically created each time the URL changes. You can read more about locations in [the `history` docs](https://github.com/rackt/history/blob/master/docs/Location.md).
56+
57+
### Pathname
58+
59+
type Pathname = string;
60+
61+
A *pathname* is the portion of a URL that describes a hierarchical path, including the preceeding `/`. For example, in `http://example.com/the/path?the=query`, `/the/path` is the pathname. It is synonymous with `window.location.pathname` in web browsers.
62+
63+
### QueryString
64+
65+
type QueryString = string;
66+
67+
A *query string* is the portion of the URL that trails the [pathname](#pathname), including the preceeding `?`. For example, in `http://example.com/the/path?the=query`, `?the=query` is the query string. It is synonymous with `window.location.search` in web browsers.
68+
69+
### Query
70+
71+
type Query = Object;
72+
73+
A *query* is the parsed version of a [query string](#querystring).
74+
75+
### Params
76+
77+
type Params = Object;
78+
79+
The word *params* refers to an object of key/value pairs that were parsed out of the original URL's [pathname](#pathname). The values of this object are typically strings, unless there is more than one param with the same name in which case the value is an array.
80+
81+
### RedirectFunction
82+
83+
type RedirectFunction = (pathname: Pathname, query: Query | any, state: any) => void;
84+
85+
A *redirect function* is used in [`onEnter` hooks](#enterhook) to trigger a transition to a new URL.
86+
87+
### RoutePattern
88+
89+
type RoutePattern = string;
90+
91+
A *route pattern* (or "path") is a string that describes a portion of a URL. Patterns are compiled into functions that are used to try and match a URL. Patterns may use the following special characters:
92+
93+
- `:paramName` – matches a URL segment up to the next `/`, `?`, or `#`. The matched string is called a [param](#params)
94+
- `()` – Wraps a portion of the URL that is optional
95+
- `*` – Matches all characters (non-greedy) up to the next character in the pattern, or to the end of the URL if there is none, and creates a `splat` param
96+
97+
Route patterns are relative to the pattern of the parent route unless they begin with a `/`, in which case they begin matching at the beginning of the URL.
98+
99+
### Route
100+
101+
type Route = {
102+
path: RoutePattern;
103+
component: Component;
104+
onEnter: EnterHook;
105+
onLeave: LeaveHook;
106+
};
107+
108+
### RoutingState
109+
110+
type RoutingState = {
111+
location: Location;
112+
routes: Array<Route>;
113+
params: Params;
114+
components: Array<Component>;
115+
};
116+
117+
A *routing state* represents the current state of a router. It contains:
118+
119+
- the current [`location`](#location),
120+
- an array of [`routes`](#route) that match that location,
121+
- an object of [`params`](#params) that were parsed out of the URL, and
122+
- an array of [`components`](#component) that will be rendered to the page in hierarchical order.

docs/Introduction.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
## Introduction
2+
3+
To illustrate the problems React Router is going to solve for you, let's build a small application without it.
4+
5+
### Without React Router
6+
7+
```js
8+
var About = React.createClass({/*...*/});
9+
var Inbox = React.createClass({/*...*/});
10+
var Home = React.createClass({/*...*/});
11+
12+
var App = React.createClass({
13+
getInitialState() {
14+
return {
15+
route: window.location.hash.substr(1)
16+
};
17+
},
18+
19+
componentDidMount() {
20+
window.addEventListener('hashchange', () => {
21+
this.setState({
22+
route: window.location.hash.substr(1)
23+
});
24+
});
25+
},
26+
27+
render() {
28+
var Child;
29+
switch (this.state.route) {
30+
case '/about': Child = About; break;
31+
case '/inbox': Child = Inbox; break;
32+
default: Child = Home;
33+
}
34+
35+
return (
36+
<div>
37+
<h1>App</h1>
38+
<ul>
39+
<li><a href="#/about">About</a></li>
40+
<li><a href="#/inbox">Inbox</a></li>
41+
</ul>
42+
<Child/>
43+
</div>
44+
)
45+
}
46+
});
47+
48+
React.render(<App />, document.body);
49+
```
50+
51+
As the hash portion of the URL changes, `<App>` will render a different `<Child>` by branching on `this.state.route`. Pretty straightforward stuff. But it gets complicated fast.
52+
53+
Imagine now that `Inbox` has some nested UI at different URLs, maybe something like this master detail view:
54+
55+
```
56+
path: /inbox/messages/1234
57+
58+
+---------+------------+------------------------+
59+
| About | Inbox | |
60+
+---------+ +------------------------+
61+
| Compose Reply Reply All Archive |
62+
+-----------------------------------------------+
63+
|Movie tomorrow| |
64+
+--------------+ Subject: TPS Report |
65+
|TPS Report From: [email protected] |
66+
+--------------+ |
67+
|New Pull Reque| So ... |
68+
+--------------+ |
69+
|... | |
70+
+--------------+--------------------------------+
71+
```
72+
73+
And maybe a stats page when not viewing a message:
74+
75+
```
76+
path: /inbox
77+
78+
+---------+------------+------------------------+
79+
| About | Inbox | |
80+
+---------+ +------------------------+
81+
| Compose Reply Reply All Archive |
82+
+-----------------------------------------------+
83+
|Movie tomorrow| |
84+
+--------------+ 10 Unread Messages |
85+
|TPS Report | 22 drafts |
86+
+--------------+ |
87+
|New Pull Reque| |
88+
+--------------+ |
89+
|... | |
90+
+--------------+--------------------------------+
91+
```
92+
93+
We'd have to make our URL parsing a lot smarter, and we would end up with a lot of code to figure out which branch of nested components to be rendered at any given URL: `App -> About`, `App -> Inbox -> Messages -> Message`, `App -> Inbox -> Messages -> Stats`, etc.
94+
95+
### With React Router
96+
97+
Let's refactor our app to use React Router.
98+
99+
```js
100+
// first we import some components
101+
import { Router, Route, Link } from 'react-router';
102+
103+
// then we delete a bunch of code from `App` and add some `Link`
104+
// components
105+
var App = React.createClass({
106+
render() {
107+
return (
108+
<div>
109+
<h1>App</h1>
110+
{/* change the <a>s to <Links>s */}
111+
<ul>
112+
<li><Link to="/about">About</Link></li>
113+
<li><Link to="/inbox">Inbox</Link></li>
114+
</ul>
115+
116+
{/*
117+
next we replace `<Child>` with `this.props.children`
118+
the router will figure out the children for us
119+
*/}
120+
{this.props.children}
121+
</div>
122+
)
123+
}
124+
});
125+
126+
// Finally we render a Router component with some Routes.
127+
// It does all the fancy routing stuff for us.
128+
React.render((
129+
<Router>
130+
<Route path="/" component={App}>
131+
<Route path="about" component={About} />
132+
<Route path="inbox" component={Inbox} />
133+
</Route>
134+
</Router>
135+
), document.body);
136+
```
137+
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:
139+
140+
```js
141+
var routes = {
142+
path: '/',
143+
component: App,
144+
childRoutes: [
145+
{ path: 'about', component: About },
146+
{ path: 'inbox', component: Inbox },
147+
]
148+
};
149+
150+
React.render(<Router routes={routes} />, document.body);
151+
```
152+
153+
### Adding more UI
154+
155+
Alright, now we're ready to nest the inbox messages inside the inbox UI.
156+
157+
```js
158+
// Make a new component to render inside of Inbox
159+
var Message = React.createClass({
160+
render() {
161+
return <h3>Message</h3>;
162+
}
163+
});
164+
165+
var Inbox = React.createClass({
166+
render() {
167+
return (
168+
<div>
169+
<h2>Inbox</h2>
170+
{/* Render the child route component */}
171+
{this.props.children || "Welcome to your Inbox"}
172+
</div>
173+
);
174+
}
175+
});
176+
177+
React.render((
178+
<Router>
179+
<Route path="/" component={App}>
180+
<Route path="about" component={About}/>
181+
<Route path="inbox" component={Inbox}>
182+
{/* Add the route, nested where we want the UI to nest */}
183+
<Route path="messages/:id" component={Message}/>
184+
</Route>
185+
</Route>
186+
</Router>
187+
), document.body);
188+
```
189+
190+
Now visits to URLs like `inbox/messages/Jkei3c32` will match the new route and nest the UI branch of `App -> Inbox -> Message`.
191+
192+
### Getting URL parameters
193+
194+
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`.
195+
196+
```js
197+
var Message = React.createClass({
198+
199+
componentDidMount() {
200+
// from the path `/inbox/messages/:id`
201+
var id = this.props.params.id;
202+
203+
fetchMessage(id, function (err, message) {
204+
this.setState({ message: message });
205+
});
206+
},
207+
208+
// ...
209+
210+
});
211+
```
212+
213+
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.

docs/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Table of Contents
2+
3+
- [Introduction](Introduction.md)
4+
- [Getting Started](GettingStarted.md)
5+
- [Dynamic Routing](DynamicRouting.md)
6+
- [Advanced Usage](AdvancedUsage.md)
7+
- [Server Rendering](ServerRendering.md)
8+
- [Transitions](Transitions.md)

0 commit comments

Comments
 (0)