Skip to content

Commit 1438571

Browse files
committed
Add docs about transitions
1 parent f29a02f commit 1438571

File tree

4 files changed

+79
-63
lines changed

4 files changed

+79
-63
lines changed

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/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
- [Introduction](Introduction.md)
44
- [Route Configuration](RouteConfiguration.md)
55
- [Route Matching](RouteMatching.md)
6-
- [Transitions](Transitions.md)
6+
- [Confirming Navigation](ConfirmingNavigation.md)
77
- [Glossary](Glossary.md)
88

99
- [Dynamic Routing](DynamicRouting.md)

docs/RouteConfiguration.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ URL | Components
6767

6868
### Adding an Index
6969

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>` to specify a "default" page.
70+
Imagine we'd like to render another component inside of `App` when the URL is `/`. Currently, `this.props.children` inside of `App`'s `render` method is `undefined` in this case. We can use an `<IndexRoute>` to specify a "default" page.
7171

7272
```js
7373
import { IndexRoute } from 'react-router';
@@ -92,7 +92,7 @@ React.render((
9292
), document.body);
9393
```
9494

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.
95+
Now, inside `App`'s `render` method `this.props.children` will be a `<Dashboard>` element! 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, both of which allow you to specify a file such as `index.html` when the request URL matches a directory path.
9696

9797
Our sitemap now looks like this:
9898

@@ -105,7 +105,7 @@ URL | Components
105105

106106
### Decoupling the UI from the URL
107107

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.
108+
It would be nice if we could remove the `/inbox` segment from the `/inbox/messages/:id` URL pattern, but still render `Message` nested inside the `App -> Inbox` UI. Absolute `path`s let us do exactly that.
109109

110110
```js
111111
React.render((
@@ -122,6 +122,8 @@ React.render((
122122
), document.body);
123123
```
124124

125+
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.
126+
125127
We can now render the following URLs:
126128

127129
URL | Components
@@ -131,15 +133,13 @@ URL | Components
131133
`/inbox` | `App -> Inbox`
132134
`/messages/:id` | `App -> Inbox -> Message`
133135

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-
136136
**Note**: Absolute paths may not be used in route config that is [dynamically loaded](DynamicLoading.md).
137137

138138
### Preserving URLs
139139

140-
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**. :(
140+
Wait 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**. :(
141141

142-
Not to worry. Redirects to the rescue!
142+
Not to worry. We can use a `<Redirect>` to make sure that URL still works!
143143

144144
```js
145145
import { Redirect } from 'react-router';
@@ -160,11 +160,23 @@ React.render((
160160
), document.body);
161161
```
162162

163-
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:
163+
Now when someone clicks on that link to `/inbox/messages/5` they'll automatically be redirected to `/messages/5`. :highfive:
164+
165+
### Enter and Leave Hooks
166+
167+
[Route](Glossary.md#route)s may also define [`onEnter`](Glossary.md#enterhook) and [`onLeave`](Glossary.md#leavehook) hooks that are invoked once a transition has been [confirmed](ConfirmingNavigation.md). These hooks are useful for various things like [requiring auth](https://github.com/rackt/react-router/tree/master/examples/auth-flow) when a route is entered and saving stuff to persistent storage before a route unmounts.
168+
169+
During a transition, [`onLeave` hooks](Glossary.md#leavehook) run first on all routes we are leaving, starting with the leaf route on up to the first common ancestor route. Next, [`onEnter` hooks](Glossary.md#enterhook) run starting with the first parent route we're entering down to the leaf route.
170+
171+
Continuing with our example above, if a user clicked on a link to `/about` from `/messages/5`, the following hooks would run in this order:
172+
173+
- `onLeave` on the `/messages/:id` route
174+
- `onLeave` on the `/inbox` route
175+
- `onEnter` on the `/about` route
164176

165177
### Alternate Configuration
166178

167-
Since [route](Glossary.md#route)s are usually nested, it's useful to use a concise nested syntax like [JSX](https://facebook.github.io/jsx/) to describe their relationship to one another. However, you may use an array of [route](Glossary.md#route) objects if you prefer to avoid using JSX.
179+
Since [route](Glossary.md#route)s are usually nested, it's useful to use a concise nested syntax like [JSX](https://facebook.github.io/jsx/) to describe their relationship to one another. However, you may also use an array of plain [route](Glossary.md#route) objects if you prefer to avoid using JSX.
168180

169181
The route config we've discussed up to this point could also be specified like this:
170182

docs/Transitions.md

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)