Skip to content

Commit

Permalink
Merge branch 'master' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
timdorr committed Apr 18, 2016
2 parents 1a73278 + a11a10b commit 3739c0e
Show file tree
Hide file tree
Showing 21 changed files with 161 additions and 64 deletions.
56 changes: 47 additions & 9 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,53 @@ An `<IndexLink>` is like a [`<Link>`](#link), except it is only active when the
### `<RouterContext>`
A `<RouterContext>` renders the component tree for a given router state. Its used by `<Router>` but also useful for server rendering and integrating in brownfield development.

It also provides a `router` object on `context`.
It also provides a `router` object on [context](https://facebook.github.io/react/docs/context.html).

#### `context.router`

Contains data and methods relevant to routing. Most useful for imperatively transitioning around the application.

To use it, you must signal to React that you need it by declaring your use of it in your component:

```js
var MyComponent = React.createClass({
contextTypes: {
router: Router.PropTypes.router
},
render: function() {
// here, you can use `this.context.router`
}
});

```

Using `context.router` in combination with ES6 classes requires a different pattern (note the use of the `static` keyword):

```js
class MyComponent extends React.Component {
static contextTypes = {
router: Router.PropTypes.router
}

render: function() {
// here, you can use `this.context.router`
}
});

```

Finally, you can use `context.router` with
[stateless function components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions):

```js
function MyComponent(props, context) {
// here, you can use `context.router`
}
MyComponent.contextTypes = {
router: Router.PropTypes.router
}
```

##### `push(pathOrLoc)`
Transitions to a new URL, adding a new entry in the browser history.

Expand Down Expand Up @@ -639,14 +680,11 @@ One or many [`<Route>`](#route)s or [`PlainRoute`](#plainroute)s.


### `PropTypes`
The following objects are exposed as properties of the exported PropTypes object:
- `falsy`: Checks that a component does not have a prop
- `history`
- `location`
- `component`
- `components`
- `route`
- `routes`
The following prop types are exported at top level and from `react-router/lib/PropTypes`:
- `routerShape`: Shape for the `router` object on context
- `locationShape`: Shape for the `location` object on route component props

Previously, a number of prop types intended for internal use were also exported under `PropTypes`. These are deprecated and should not be used.


### `useRoutes(createHistory)` (deprecated)
Expand Down
2 changes: 1 addition & 1 deletion docs/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ You need to add `router` to your component's `contextTypes` to make the router o

```js
contextTypes: {
router: Router.PropTypes.router
router: routerShape.isRequired
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/ConfirmingNavigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ You can prevent a transition from happening or prompt the user before leaving a
const Home = React.createClass({

contextTypes: {
router: Router.PropTypes.router
router: routerShape.isRequired
},

componentDidMount() {
Expand Down
8 changes: 5 additions & 3 deletions examples/auth-flow-async-with-query-params/app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { createClass, PropTypes } from 'react'
import React, { createClass } from 'react'
import { render } from 'react-dom'
import { Router, Route, IndexRoute, browserHistory, Link } from 'react-router'
import {
Router, Route, IndexRoute, browserHistory, Link, routerShape
} from 'react-router'

function App(props) {
return (
Expand All @@ -12,7 +14,7 @@ function App(props) {

const Form = createClass({
contextTypes: {
router: PropTypes.object.isRequired
router: routerShape.isRequired
},

getInitialState() {
Expand Down
4 changes: 2 additions & 2 deletions examples/auth-flow/app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { render } from 'react-dom'
import { browserHistory, Router, Route, Link } from 'react-router'
import { browserHistory, Router, Route, Link, routerShape } from 'react-router'
import auth from './auth'

const App = React.createClass({
Expand Down Expand Up @@ -58,7 +58,7 @@ const Dashboard = React.createClass({
const Login = React.createClass({

contextTypes: {
router: React.PropTypes.object.isRequired
router: routerShape.isRequired
},

getInitialState() {
Expand Down
4 changes: 2 additions & 2 deletions examples/confirming-navigation/app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { render } from 'react-dom'
import { browserHistory, Router, Route, Link } from 'react-router'
import { browserHistory, Router, Route, Link, routerShape } from 'react-router'

const App = React.createClass({
render() {
Expand All @@ -24,7 +24,7 @@ const Dashboard = React.createClass({

const Form = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
router: routerShape.isRequired
},

componentWillMount() {
Expand Down
8 changes: 5 additions & 3 deletions examples/master-detail/app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react'
import { render, findDOMNode } from 'react-dom'
import { browserHistory, Router, Route, IndexRoute, Link } from 'react-router'
import {
browserHistory, Router, Route, IndexRoute, Link, routerShape
} from 'react-router'
import ContactStore from './ContactStore'
import './app.css'

Expand Down Expand Up @@ -63,7 +65,7 @@ const Index = React.createClass({

const Contact = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
router: routerShape.isRequired
},

getStateFromStore(props) {
Expand Down Expand Up @@ -120,7 +122,7 @@ const Contact = React.createClass({

const NewContact = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
router: routerShape.isRequired
},

createContact(event) {
Expand Down
4 changes: 2 additions & 2 deletions examples/passing-props-to-children/app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'
import { render } from 'react-dom'
import { browserHistory, Router, Route, Link } from 'react-router'
import { browserHistory, Router, Route, Link, routerShape } from 'react-router'
import './app.css'

const App = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
router: routerShape.isRequired
},

getInitialState() {
Expand Down
2 changes: 1 addition & 1 deletion modules/History.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import warning from './routerWarning'
import { history } from './PropTypes'
import { history } from './InternalPropTypes'

/**
* A mixin that adds the "history" instance variable to components.
Expand Down
2 changes: 1 addition & 1 deletion modules/IndexRedirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import warning from './routerWarning'
import invariant from 'invariant'
import Redirect from './Redirect'
import { falsy } from './PropTypes'
import { falsy } from './InternalPropTypes'

const { string, object } = React.PropTypes

Expand Down
2 changes: 1 addition & 1 deletion modules/IndexRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import warning from './routerWarning'
import invariant from 'invariant'
import { createRouteFromReactElement } from './RouteUtils'
import { component, components, falsy } from './PropTypes'
import { component, components, falsy } from './InternalPropTypes'

const { func } = React.PropTypes

Expand Down
22 changes: 22 additions & 0 deletions modules/InternalPropTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { PropTypes } from 'react'

const { func, object, arrayOf, oneOfType, element, shape, string } = PropTypes

export function falsy(props, propName, componentName) {
if (props[propName])
return new Error(`<${componentName}> should not have a "${propName}" prop`)
}

export const history = shape({
listen: func.isRequired,
push: func.isRequired,
replace: func.isRequired,
go: func.isRequired,
goBack: func.isRequired,
goForward: func.isRequired
})

export const component = oneOfType([ func, string ])
export const components = oneOfType([ component, object ])
export const route = oneOfType([ object, element ])
export const routes = oneOfType([ route, arrayOf(route) ])
3 changes: 2 additions & 1 deletion modules/Link.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import warning from './routerWarning'
import { routerShape } from './PropTypes'

const { bool, object, string, func, oneOfType } = React.PropTypes

Expand Down Expand Up @@ -49,7 +50,7 @@ function createLocationDescriptor(to, { query, hash, state }) {
const Link = React.createClass({

contextTypes: {
router: object
router: routerShape
},

propTypes: {
Expand Down
78 changes: 55 additions & 23 deletions modules/PropTypes.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,78 @@
import { PropTypes } from 'react'

const { func, object, arrayOf, oneOfType, element, shape, string } = PropTypes
import deprecateObjectProperties from './deprecateObjectProperties'
import * as InternalPropTypes from './InternalPropTypes'
import warning from './routerWarning'

export function falsy(props, propName, componentName) {
if (props[propName])
return new Error(`<${componentName}> should not have a "${propName}" prop`)
}
const { func, object, shape, string } = PropTypes

export const history = shape({
listen: func.isRequired,
export const routerShape = shape({
push: func.isRequired,
replace: func.isRequired,
go: func.isRequired,
goBack: func.isRequired,
goForward: func.isRequired
goForward: func.isRequired,
setRouteLeaveHook: func.isRequired,
isActive: func.isRequired
})

export const location = shape({
export const locationShape = shape({
pathname: string.isRequired,
search: string.isRequired,
state: object,
action: string.isRequired,
key: string
})

export const component = oneOfType([ func, string ])
export const components = oneOfType([ component, object ])
export const route = oneOfType([ object, element ])
export const routes = oneOfType([ route, arrayOf(route) ])
// Deprecated stuff below:

export const router = shape({
push: func.isRequired,
replace: func.isRequired,
go: func.isRequired,
goBack: func.isRequired,
goForward: func.isRequired,
setRouteLeaveHook: func.isRequired,
isActive: func.isRequired
})
export let falsy = InternalPropTypes.falsy
export let history = InternalPropTypes.history
export let location = locationShape
export let component = InternalPropTypes.component
export let components = InternalPropTypes.components
export let route = InternalPropTypes.route
export let routes = InternalPropTypes.routes
export let router = routerShape

if (__DEV__) {
const deprecatePropType = (propType, message) => (...args) => {
warning(false, message)
return propType(...args)
}

const deprecateInternalPropType = propType => (
deprecatePropType(propType, 'This prop type is not intended for external use, and was previously exported by mistake. These internal prop types are deprecated for external use, and will be removed in a later version.')
)

const deprecateRenamedPropType = (propType, name) => (
deprecatePropType(propType, `The \`${name}\` prop type is now exported as \`${name}Shape\` to avoid name conflicts. This export is deprecated and will be removed in a later version.`)
)

falsy = deprecateInternalPropType(falsy)
history = deprecateInternalPropType(history)
component = deprecateInternalPropType(component)
components = deprecateInternalPropType(components)
route = deprecateInternalPropType(route)
routes = deprecateInternalPropType(routes)

export default {
location = deprecateRenamedPropType(location, 'location')
router = deprecateRenamedPropType(router, 'router')
}

let defaultExport = {
falsy,
history,
location,
component,
components,
route,
// For some reason, routes was never here.
router
}

if (__DEV__) {
defaultExport = deprecateObjectProperties(defaultExport, 'The default export from `react-router/lib/PropTypes` is deprecated. Please use the named exports instead.')
}

export default defaultExport
2 changes: 1 addition & 1 deletion modules/Redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import invariant from 'invariant'
import { createRouteFromReactElement } from './RouteUtils'
import { formatPattern } from './PatternUtils'
import { falsy } from './PropTypes'
import { falsy } from './InternalPropTypes'

const { string, object } = React.PropTypes

Expand Down
2 changes: 1 addition & 1 deletion modules/Route.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import invariant from 'invariant'
import { createRouteFromReactElement } from './RouteUtils'
import { component, components } from './PropTypes'
import { component, components } from './InternalPropTypes'

const { string, func } = React.PropTypes

Expand Down
2 changes: 1 addition & 1 deletion modules/Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import useQueries from 'history/lib/useQueries'
import React from 'react'

import createTransitionManager from './createTransitionManager'
import { routes } from './PropTypes'
import { routes } from './InternalPropTypes'
import RouterContext from './RouterContext'
import { createRoutes } from './RouteUtils'
import { createRouterObject, createRoutingHistory } from './RouterUtils'
Expand Down
4 changes: 2 additions & 2 deletions modules/__tests__/RouterContext-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react'
import { render, unmountComponentAtNode } from 'react-dom'

import match from '../match'
import { router as routerPropType } from '../PropTypes'
import { routerShape } from '../PropTypes'
import RouterContext from '../RouterContext'
import { createRouterObject } from '../RouterUtils'

Expand Down Expand Up @@ -42,7 +42,7 @@ describe('RouterContext', () => {
}

Component.contextTypes = {
router: routerPropType.isRequired
router: routerShape.isRequired
}

routes = { path: '/', component: Component }
Expand Down
Loading

0 comments on commit 3739c0e

Please sign in to comment.