diff --git a/docs/api/README.md b/docs/api/README.md
index 8dabbedf4c..0b7d003915 100644
--- a/docs/api/README.md
+++ b/docs/api/README.md
@@ -1,8 +1,9 @@
-React Router API
+React Router API
================
- [`Router.run`](/docs/api/run.md)
- [`Router.create`](/docs/api/create.md)
+- [`Router Context`](/docs/api/RouterContext.md)
- [`Location`](/docs/api/Location.md)
- [`Transition`](/docs/api/Transition.md)
diff --git a/docs/api/RouterContext.md b/docs/api/RouterContext.md
new file mode 100644
index 0000000000..7fd562267f
--- /dev/null
+++ b/docs/api/RouterContext.md
@@ -0,0 +1,160 @@
+API: Router Context
+===================
+
+The `context` feature of React is undocumented because its not
+completely baked yet, however, it is commited to by the React team and
+we use it with great effect in the Router. There are plans to make
+reliance on context optional, but for now, this is what we use.
+
+You access the router inside of route handlers with
+`this.context.router`. Its got a few useful methods on it.
+
+### `transitionTo(routeNameOrPath, [params[, query]])`
+
+Programmatically transition to a new route.
+
+#### Examples
+
+```js
+this.context.router.transitionTo('user', {id: 10}, {showAge: true});
+this.context.router.transitionTo('about');
+this.context.router.transitionTo('/users/10?showAge=true');
+this.context.router.transitionTo('http://example.com/users/10?showAge=true');
+```
+
+### `replaceWith(routeNameOrPath, [params[, query]])`
+
+Programmatically replace current route with a new route. Does not add an
+entry into the browser history.
+
+#### Examples
+
+```js
+this.context.router.replaceWith('user', {id: 10}, {showAge: true});
+this.context.router.replaceWith('about');
+this.context.router.replaceWith('/users/10?showAge=true');
+```
+
+### `goBack()`
+
+Programmatically go back to the last route and remove the most recent
+entry from the browser history. Returns `true` unless it's the first entry
+in the app history.
+
+#### Example
+
+```js
+this.context.router.goBack();
+```
+
+If you want to make sure there was a history entry to go back to, use the return value:
+
+```js
+if (!this.context.router.goBack()) {
+ this.context.router.transitionTo('/otherpage')
+}
+```
+
+### `makePath(routeName, params, query)`
+
+Creates a URL path to a route.
+
+### `makeHref(routeName, params, query)`
+
+Creates an `href` to a route.
+
+#### Example
+
+```js
+// given a route like this:
+//
+this.context.router.makeHref('user', {userId: 123}); // "users/123"
+```
+
+### `getPath()`
+
+Returns the current URL path, including query string.
+
+### `getPathname()`
+
+Returns the current URL path without the query string.
+
+### `getParams()`
+
+Returns a hash of the currently active URL params.
+
+### `getQuery()`
+
+Returns a hash of the currently active query params.
+
+### `isActive(routeName, params, query)`
+
+Returns `true` if a route, params, and query are active, `false`
+otherwise.
+
+### `getRoutes()`
+
+Returns an array of the currently active routes, in nesting order.
+
+Examples
+--------
+
+Often you'll want access to params and query:
+
+```js
+// route
+
+
+// handler
+var User = React.createClass({
+ render: function () {
+ var name = this.context.router.getParams().name;
+ return (
+
+
{name}
+
+ );
+ }
+});
+```
+
+Let's say you are using bootstrap and want to get `active` on those `li`
+tags for the Tabs:
+
+```js
+var Link = require('react-router').Link;
+
+var Tab = React.createClass({
+ render: function () {
+ var { router } = this.context;
+ var isActive = router.isActive(this.props.to, this.props.params, this.props.query);
+ var className = isActive ? 'active' : '';
+ var link = (
+
+ );
+ return
{link}
;
+ }
+
+});
+
+// use it just like , and you'll get an anchor wrapped in an `li`
+// with an automatic `active` class on both.
+Foo
+```
+
+Some navigation:
+
+```js
+React.createClass({
+ render: function() {
+ var { router } = this.context;
+ return (
+
router.transitionTo('foo')}>Go to foo
+
router.replaceWith('bar')}>Go to bar without creating a new history entry
+
router.goBack()}>Go back
+ );
+ }
+});
+```
+
+
diff --git a/docs/api/components/RouteHandler.md b/docs/api/components/RouteHandler.md
index 6f3d858ff8..9b79a0912b 100644
--- a/docs/api/components/RouteHandler.md
+++ b/docs/api/components/RouteHandler.md
@@ -4,6 +4,14 @@ API: `RouteHandler` (component)
A `` renders the handler of the route at the level of the
route hierarchy in which it is used.
+Router Context
+--------------
+
+Router handlers are rendered with a router in their context with useful
+methods.
+
+Please see [`Router Context`](/docs/api/RouterContext.md)
+
Static Lifecycle Methods
------------------------
@@ -53,3 +61,4 @@ var Settings = React.createClass({
//...
});
```
+
diff --git a/docs/api/mixins/Navigation.md b/docs/api/mixins/Navigation.md
index 3377ecd74d..3449f73e79 100644
--- a/docs/api/mixins/Navigation.md
+++ b/docs/api/mixins/Navigation.md
@@ -1,90 +1,5 @@
API: `Navigation` (mixin)
==========================
-A mixin for components that need to create URLs and/or initiate
-transitions to other routes.
+Deprecated, please see [Router Context](/docs/api/RouterContext.md)
-Instance Methods
-----------------
-
-### `transitionTo(routeNameOrPath, [params[, query]])`
-
-Programmatically transition to a new route.
-
-#### Examples
-
-```js
-this.transitionTo('user', {id: 10}, {showAge: true});
-this.transitionTo('about');
-this.transitionTo('/users/10?showAge=true');
-this.transitionTo('http://example.com/users/10?showAge=true');
-```
-
-### `replaceWith(routeNameOrPath, [params[, query]])`
-
-Programmatically replace current route with a new route. Does not add an
-entry into the browser history.
-
-#### Examples
-
-```js
-this.replaceWith('user', {id: 10}, {showAge: true});
-this.replaceWith('about');
-this.replaceWith('/users/10?showAge=true');
-```
-
-### `goBack()`
-
-Programmatically go back to the last route and remove the most recent
-entry from the browser history. Returns `true` unless it's the first entry
-in the app history.
-
-#### Example
-
-```js
-this.goBack();
-```
-
-If you want to make sure there was a history entry to go back to, use the return value:
-
-```js
-if (!this.goBack()) {
- this.transitionTo('/otherpage')
-}
-```
-
-### `makePath(routeName, params, query)`
-
-Creates a URL path to a route.
-
-### `makeHref(routeName, params, query)`
-
-Creates an `href` to a route. Use this along with `State` when you
-need to build components similar to `Link`.
-
-#### Example
-
-```js
-// given a route like this:
-//
-this.makeHref('user', {userId: 123}); // "users/123"
-```
-
-Example
--------
-
-```js
-var Navigation = require('react-router').Navigation;
-
-React.createClass({
- mixins: [Navigation],
-
- render: function() {
- return (
-
this.transitionTo('foo')}>Go to foo
-
this.replaceWith('bar')}>Go to bar without creating a new history entry
-
this.goBack()}>Go back
- );
- }
-});
-```
diff --git a/docs/api/mixins/State.md b/docs/api/mixins/State.md
index 90fbb82957..9313d2df87 100644
--- a/docs/api/mixins/State.md
+++ b/docs/api/mixins/State.md
@@ -1,85 +1,6 @@
API: `State` (mixin)
==========================
-A mixin for components that need to know about the active params, query
-and routes. Any handler on a route with dynamic segments will want to
-use this.
+Deprecated, please see [Router Context](/docs/api/RouterContext.md)
-Instance Methods
-----------------
-### `getPath()`
-
-Returns the current URL path, including query string.
-
-### `getPathname()`
-
-Returns the current URL path without the query string.
-
-### `getParams()`
-
-Returns a hash of the currently active URL params.
-
-### `getQuery()`
-
-Returns a hash of the currently active query params.
-
-### `isActive(routeName, params, query)`
-
-Returns `true` if a route, params, and query are active, `false`
-otherwise.
-
-### `getRoutes()`
-
-Returns an array of the currently active routes, in nesting order.
-
-Examples
---------
-
-Usually you'll just want access to params and query:
-
-```js
-// route
-
-
-// handler
-var User = React.createClass({
- mixins: [ Router.State ],
-
- render: function () {
- var name = this.getParams().name;
- return (
-
-
{name}
-
- );
- }
-});
-```
-
-Let's say you are using bootstrap and want to get `active` on those `li`
-tags for the Tabs:
-
-```js
-var Link = require('react-router').Link;
-var State = require('react-router').State;
-
-var Tab = React.createClass({
-
- mixins: [ State ],
-
- render: function () {
- var isActive = this.isActive(this.props.to, this.props.params, this.props.query);
- var className = isActive ? 'active' : '';
- var link = (
-
- );
- return
{link}
;
- }
-
-});
-
-// use it just like , and you'll get an anchor wrapped in an `li`
-// with an automatic `active` class on both.
-Foo
-```
diff --git a/docs/guides/flux.md b/docs/guides/flux.md
index ea290a7317..60950aa84f 100644
--- a/docs/guides/flux.md
+++ b/docs/guides/flux.md
@@ -13,21 +13,19 @@ creating a cycle indirectly.
To avoid this, you can do one of three things:
-1. Send the component to the action, think of it like `event.target` in
- DOM events if it bothers you.
+1. Send the router context to the action:
```js
var SomeActionCreators = require('./SomeActionCreators');
var Something = React.createClass({
- mixins: [ Router.Navigation ],
handleClick () {
- SomeActionCreators.doStuff({ sourceComponent: this });
+ SomeActionCreators.doStuff({ router: this.context.router });
}
});
```
and then in `SomeActionCreators.doStuff` call
- `payload.sourceComponent.transitionTo(...)`
+ `payload.router.transitionTo(...)`
2. Use some sort of application container, or module container for the
router instance.
@@ -112,9 +110,8 @@ To avoid this, you can do one of three things:
}
```
-
Accessing route and params from action creators
----------------------------------
+-----------------------------------------------
You can create your own `RouterStore` and fire an action in `run` callback:
diff --git a/docs/guides/overview.md b/docs/guides/overview.md
index d2c23e9dcb..222d51a664 100644
--- a/docs/guides/overview.md
+++ b/docs/guides/overview.md
@@ -285,8 +285,8 @@ Dynamic Segments
When we added the `message` route, we introduced a "dynamic segment" to
the URL. These segments get parsed from the url and are available in
-the `run` callback, or from the `State` mixin. Let's see how we can
-access the params.
+the `run` callback, or from `this.context.router` in a route handler.
+Let's see how we can access the params.
Remember our message route looks like this:
@@ -298,16 +298,15 @@ Lets look at accessing the `messageId` in `Message`.
```js
var Message = React.createClass({
- mixins: [Router.State],
render: function () {
return (
-
{this.getParams().messageId}
+
{this.context.router.getParams().messageId}
);
}
});
```
-Assuming the user navigates to `/inbox/123`, `this.getParams().messageId` is
+Assuming the user navigates to `/inbox/123`, `this.context.router.getParams().messageId` is
going to be `'123'`.
Alternatively, you can pass the param data down through the view
@@ -361,13 +360,11 @@ If you would rather force route handlers to re-mount when transitioning between
```js
var App = React.createClass({
-
- mixins: [Router.State],
-
getHandlerKey: function () {
var childDepth = 1; // assuming App is top-level route
- var key = this.getRoutes()[childDepth].name;
- var id = this.getParams().id;
+ var { router } = this.context;
+ var key = router.getRoutes()[childDepth].name;
+ var id = router.getParams().id;
if (id) { key += id; }
return key;
},
@@ -447,12 +444,6 @@ That's the gist of what this router is all about, but there's a lot more
it has to offer. Check out the [API Docs][API] to learn about
redirecting transitions, query parameters and more.
- [AsyncState]:../api/mixins/AsyncState.md
- [Route]:../api/components/Route.md
- [create]: ../api/create.md
- [API]:../api/
- [path-matching]:./path-matching.md
-
CommonJS Guide
--------------
diff --git a/docs/guides/testing.md b/docs/guides/testing.md
index b86096c3cd..83f24e7ce0 100644
--- a/docs/guides/testing.md
+++ b/docs/guides/testing.md
@@ -3,7 +3,7 @@ React Router Testing
Because the router relies heavily on the lesser known `context` feature
of React, it can be a pain in the neck to test your components that have
-things like `` or mixin `State` and `Navigation`.
+things like `` or rely on `this.context.router`.
You simply have to stub out the context you need.
@@ -15,17 +15,7 @@ React.render(, testElement);
You'll get something like:
```
-"Warning: Required context `makePath` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `makeHref` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `transitionTo` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `replaceWith` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `goBack` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `getCurrentPath` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `getCurrentRoutes` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `getCurrentPathname` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `getCurrentParams` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `getCurrentQuery` was not specified in `Link`. Check the render method of `IndividualComponent`."
-"Warning: Required context `isActive` was not specified in `Link`. Check the render method of `IndividualComponent`."
+"Warning: Required context `router` was not specified in `Link`. Check the render method of `IndividualComponent`."
```
So we can just wrap up the thing we want to test in a different
@@ -33,36 +23,18 @@ component and stub out the `context` stuff.
```js
// wrap it up first:
-var { func } = React.PropTypes;
-
var TestWrapper = React.createClass({
childContextTypes: {
- makePath: func,
- makeHref: func,
- transitionTo: func,
- replaceWith: func,
- goBack: func,
- getCurrentPath: func,
- getCurrentRoutes: func,
- getCurrentPathname: func,
- getCurrentParams: func,
- getCurrentQuery: func,
- isActive: func,
+ router: React.PropTypes.object
},
getChildContext () {
- return {
- makePath () {},
- makeHref () {},
- transitionTo () {},
- replaceWith () {},
- goBack () {},
- getCurrentPath () {},
- getCurrentRoutes () {},
- getCurrentPathname () {},
- getCurrentParams () {},
- getCurrentQuery () {},
- isActive () {},
+ return router: {
+ makePath () {},
+ makeHref () {},
+ isActive () {},
+ // and whichever router methods your component uses
+ }
};
},
@@ -88,33 +60,25 @@ Copy/paste this helper into your test utils to make things a bit easier:
var stubRouterContext = (Component, props, stubs) => {
return React.createClass({
childContextTypes: {
- makePath: func,
- makeHref: func,
- transitionTo: func,
- replaceWith: func,
- goBack: func,
- getCurrentPath: func,
- getCurrentRoutes: func,
- getCurrentPathname: func,
- getCurrentParams: func,
- getCurrentQuery: func,
- isActive: func,
+ router: object
},
getChildContext () {
- return Object.assign({
- makePath () {},
- makeHref () {},
- transitionTo () {},
- replaceWith () {},
- goBack () {},
- getCurrentPath () {},
- getCurrentRoutes () {},
- getCurrentPathname () {},
- getCurrentParams () {},
- getCurrentQuery () {},
- isActive () {},
- }, stubs);
+ return {
+ router: Object.assign({
+ makePath () {},
+ makeHref () {},
+ transitionTo () {},
+ replaceWith () {},
+ goBack () {},
+ getCurrentPath () {},
+ getCurrentRoutes () {},
+ getCurrentPathname () {},
+ getCurrentParams () {},
+ getCurrentQuery () {},
+ isActive () {},
+ }, stubs)
+ };
},
render () {