You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Copy file name to clipboardExpand all lines: docs/RouteConfiguration.md
+21-9Lines changed: 21 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,7 +67,7 @@ URL | Components
67
67
68
68
### Adding an Index
69
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>` 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.
71
71
72
72
```js
73
73
import { IndexRoute } from'react-router';
@@ -92,7 +92,7 @@ React.render((
92
92
), document.body);
93
93
```
94
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.
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.
96
96
97
97
Our sitemap now looks like this:
98
98
@@ -105,7 +105,7 @@ URL | Components
105
105
106
106
### Decoupling the UI from the URL
107
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.
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.
109
109
110
110
```js
111
111
React.render((
@@ -122,6 +122,8 @@ React.render((
122
122
), document.body);
123
123
```
124
124
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
+
125
127
We can now render the following URLs:
126
128
127
129
URL | Components
@@ -131,15 +133,13 @@ URL | Components
131
133
`/inbox` | `App -> Inbox`
132
134
`/messages/:id` | `App -> Inbox -> Message`
133
135
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
136
**Note**: Absolute paths may not be used in route config that is [dynamically loaded](DynamicLoading.md).
137
137
138
138
### Preserving URLs
139
139
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**. :(
141
141
142
-
Not to worry. Redirects to the rescue!
142
+
Not to worry. We can use a `<Redirect>`to make sure that URL still works!
143
143
144
144
```js
145
145
import { Redirect } from'react-router';
@@ -160,11 +160,23 @@ React.render((
160
160
), document.body);
161
161
```
162
162
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
164
176
165
177
### Alternate Configuration
166
178
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.
168
180
169
181
The route config we've discussed up to this point could also be specified like this:
0 commit comments