Skip to content

Commit 88be5d5

Browse files
committed
Merge branch 'better-docs'
2 parents e1bf3b1 + e376218 commit 88be5d5

11 files changed

+801
-52
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ If you just want to drop a `<script>` tag in your page and be done with it, you
6060

6161
```js
6262
import { Router, Route } from 'react-router';
63-
import { history } from 'react-router/lib/BrowserHistory';
6463

6564
var App = React.createClass({/*...*/});
6665
var About = React.createClass({/*...*/});
@@ -109,7 +108,7 @@ var User = React.createClass({
109108
// instead, all you really need is a single root route, you don't need to
110109
// colocate the entire config).
111110
React.render((
112-
<Router history={history}>
111+
<Router>
113112
<Route path="/" component={App}>
114113
<Route path="about" component={About}/>
115114
<Route path="users" component={Users}>

docs/ConfirmingNavigation.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## Confirming Navigation
2+
3+
React Router provides a [`routerWillLeave` lifecycle hook](Glossary.md#routehook) that React [component](Glossary.md#component)s may use to prevent a transition from happening or to prompt the user before leaving a [route](Glossary.md#route). `routerWillLeave` may either 1) `return false` to cancel the transition or 2) `return` a prompt message that will prompt the user for confirmation before leaving the route.
4+
5+
To install this hook, use the `Lifecycle` mixin in one of your [route component](Glossary.md#routecomponent)s.
6+
7+
```js
8+
import { Lifecycle } from 'react-router';
9+
10+
var Home = React.createClass({
11+
12+
// Assuming Home is a route component, it may use the
13+
// Lifecycle mixin to get a routerWillLeave method.
14+
mixins: [ Lifecycle ],
15+
16+
routerWillLeave(nextLocation) {
17+
if (!this.state.isSaved)
18+
return 'Your work is not saved! Are you sure you want to leave?';
19+
},
20+
21+
// ...
22+
23+
});
24+
```
25+
26+
If you need a `routerWillLeave` hook in a deeply nested component, simply use the `RouteContext` mixin in your [route component](Glossary.md#routecomponent) to put the `route` in context.
27+
28+
```js
29+
import { Lifecycle, RouteContext } from 'react-router';
30+
31+
var Home = React.createClass({
32+
33+
// Home should provide its route in context
34+
// for descendants further down the hierarchy.
35+
mixins: [ RouteContext ],
36+
37+
render() {
38+
return <NestedForm />;
39+
}
40+
41+
});
42+
43+
var NestedForm = React.createClass({
44+
45+
// Descendants use the Lifecycle mixin to get
46+
// a routerWillLeave method.
47+
mixins: [ Lifecycle ],
48+
49+
routerWillLeave(nextLocation) {
50+
if (!this.state.isSaved)
51+
return 'Your work is not saved! Are you sure you want to leave?';
52+
},
53+
54+
// ...
55+
56+
});
57+
```

docs/DynamicRouting.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## Dynamic Routing
2+
3+
React Router is great for small sites like [React.js Training](https://reactjs-training.com) ("React Router brought to you by ...") but it's built with websites like [Facebook](https://www.facebook.com/) and [Twitter](https://twitter.com/) in mind, too.
4+
5+
The primary concern for large apps is the amount of JavaScript required to boot the app. Large apps should download only the JavaScript required to render the current view. Some people call this "code splitting"–you split your code up into multiple bundles that are loaded on-demand as the user navigates around.
6+
7+
It's important that changes deep down in the application don't require changes all the way up top as well. For example, adding a route to the photo viewer should not affect the size of the initial JavaScript bundle the user downloads. Neither should it cause merge conflicts as multiple teams have their fingers in the same, big route configuration file.
8+
9+
A router is the perfect place to handle code splitting: it's responsible for setting up your views.
10+
11+
React Router does all of its [path matching](RouteMatching.md) and component fetching asynchronously, which allows you to not only load up the components lazily, *but also lazily load the route configuration*. You really only need one route definition in your initial bundle, the router can resolve the rest on demand.
12+
13+
Routes may define `getChildRoutes` and `getComponents` methods. These are asynchronous and only called when needed. We call it "gradual matching". React Router will gradually match the URL and fetch only the amount of route configuration and components it needs to match the URL and render.
14+
15+
Coupled with a smart code splitting tool like [webpack](http://webpack.github.io/), a once tireless architecture is now simple and declarative.
16+
17+
```js
18+
var CourseRoute = {
19+
path: 'course/:courseId',
20+
21+
getChildRoutes(location, callback) {
22+
require.ensure([], function (require) {
23+
callback(null, [
24+
require('./routes/Announcements'),
25+
require('./routes/Assignments'),
26+
require('./routes/Grades'),
27+
])
28+
})
29+
},
30+
31+
getComponents(callback) {
32+
require.ensure([], function (require) {
33+
callback(null, require('./components/Course'))
34+
})
35+
}
36+
};
37+
```
38+
39+
Now go look at what hacks you have in place to do this. Just kidding, I don't want to make you sad right now.
40+
41+
Run the [huge apps](https://github.com/rackt/react-router/tree/master/examples/huge-apps) example with your web inspector open and watch code get loaded in as you navigate around the demo.

docs/Glossary.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
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: RouterState, 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 [router state](#routerstate) 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+
### LeaveHook
32+
33+
type LeaveHook = () => any;
34+
35+
A *leave hook* is a user-defined function that is called when a route is about to be unmounted.
36+
37+
### Location
38+
39+
type Location = {
40+
pathname: Pathname;
41+
search: QueryString;
42+
query: Query;
43+
state: LocationState;
44+
action: Action;
45+
key: LocationKey;
46+
};
47+
48+
A *location* answers two important (philosophical) questions:
49+
50+
- Where am I?
51+
- How did I get here?
52+
53+
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).
54+
55+
### LocationKey
56+
57+
type LocationKey = string;
58+
59+
A *location key* is a string that is unique to a particular [`location`](#location). It is the one piece of data that most accurately answers the question "Where am I?".
60+
61+
### LocationState
62+
63+
type LocationState = ?Object;
64+
65+
A *location state* is an arbitrary object of data associated with a particular [`location`](#location). This is basically a way to tie extra state to a location that is not contained in the URL.
66+
67+
This type gets its name from the first argument to HTML5's [`pushState`][pushState] and [`replaceState`][replaceState] methods.
68+
69+
[pushState]: https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method
70+
[replaceState]: https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_replaceState()_method
71+
72+
### Path
73+
74+
type Path = Pathname + QueryString;
75+
76+
A *path* represents a URL path.
77+
78+
### Pathname
79+
80+
type Pathname = string;
81+
82+
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.
83+
84+
### QueryString
85+
86+
type QueryString = string;
87+
88+
A *query string* is the portion of the URL that follows the [pathname](#pathname), including any 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.
89+
90+
### Query
91+
92+
type Query = Object;
93+
94+
A *query* is the parsed version of a [query string](#querystring).
95+
96+
### Params
97+
98+
type Params = Object;
99+
100+
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.
101+
102+
### RedirectFunction
103+
104+
type RedirectFunction = (pathname: Pathname | Path, query: ?Query, state: ?LocationState) => void;
105+
106+
A *redirect function* is used in [`onEnter` hooks](#enterhook) to trigger a transition to a new URL.
107+
108+
### Route
109+
110+
type Route = {
111+
component: RouteComponent;
112+
path: ?RoutePattern;
113+
onEnter: ?EnterHook;
114+
onLeave: ?LeaveHook;
115+
};
116+
117+
A *route* specifies a [component](#component) that is part of the user interface (UI). Routes should be nested in a tree-like structure that follows the hierarchy of your components.
118+
119+
It may help to think of a route as an "entry point" into your UI. You don't need a route for every component in your component hierarchy, only for those places where your UI differs based on the URL.
120+
121+
### RouteComponent
122+
123+
type RouteComponent = Component;
124+
125+
The term *route component* refers to a [component](#component) that is directly rendered by a [route](#route) (i.e. the `<Route component>`). The router creates elements from route components and provides them as `this.props.children` to route components further up the hierarchy. In addition to `children`, route components receive the following props:
126+
127+
- `router` – The [router](#router) instance
128+
- `location` – The current [location](#location)
129+
- `params` – The current [params](#params)
130+
- `route` – The [route](#route) that declared this component
131+
- `routeParams` – A subset of the [params](#params) that were specified in the route's [`path`](#routepattern)
132+
133+
### RouteConfig
134+
135+
type RouteConfig = Array<Route>;
136+
137+
A *route config* is an array of [route](#route)s that specifies the order in which routes should be tried when the router attempts to match a URL.
138+
139+
### RouteHook
140+
141+
type RouteHook = (nextLocation?: Location) => any;
142+
143+
A *route hook* is a function that is used to prevent the user from leaving a route. On normal transitions, it receives the next [location](#location) as an argument and must either `return false` to cancel the transition or `return` a prompt message to show the user. When invoked during the `beforeunload` event in web browsers, it does not receive any arguments and must `return` a prompt message to cancel the transition.
144+
145+
### RoutePattern
146+
147+
type RoutePattern = string;
148+
149+
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:
150+
151+
- `:paramName` – matches a URL segment up to the next `/`, `?`, or `#`. The matched string is called a [param](#params)
152+
- `()` – Wraps a portion of the URL that is optional
153+
- `*` – 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](#params)
154+
155+
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.
156+
157+
### Router
158+
159+
type Router = {
160+
transitionTo: (location: Location) => void;
161+
pushState: (state: ?LocationState, pathname: Pathname | Path, query?: Query) => void;
162+
replaceState: (state: ?LocationState, pathname: Pathname | Path, query?: Query) => void;
163+
go(n: Number) => void;
164+
listen(listener: RouterListener) => Function;
165+
match(location: Location, callback: RouterListener) => void;
166+
};
167+
168+
A *router* is a [`history`](http://rackt.github.io/history) object (akin to `window.history` in web browsers) that is used to modify and listen for changes to the URL.
169+
170+
There are two primary interfaces for computing a router's next [state](#routerstate):
171+
172+
- `history.listen` is to be used in stateful environments (such as web browsers) that need to update the UI over a period of time. This method immediately invokes its `listener` argument once and returns a function that must be called to stop listening for changes
173+
- `history.match` is a pure asynchronous function that does not update the history's internal state. This makes it ideal for server-side environments where many requests must be handled concurrently
174+
175+
### RouterListener
176+
177+
type RouterListener = (error: ?Error, nextState: RouterState) => void;
178+
179+
A *router listener* is a function that is used to listen for changes to a [router](#router)'s [state](#routerstate).
180+
181+
### RouterState
182+
183+
type RouterState = {
184+
location: Location;
185+
routes: Array<Route>;
186+
params: Params;
187+
components: Array<Component>;
188+
};
189+
190+
A *router state* represents the current state of a router. It contains:
191+
192+
- the current [`location`](#location),
193+
- an array of [`routes`](#route) that match that location,
194+
- an object of [`params`](#params) that were parsed out of the URL, and
195+
- an array of [`components`](#component) that will be rendered to the page in hierarchical order.

0 commit comments

Comments
 (0)