> **React Router v5.1.0 with hooks**
There is a new `useHistory` hook in React Router >5.1.0 if you are using React >16.8.0 and functional components.
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
> **React Router v4**
With v4 of React Router, there are three approaches that you can take to programmatic routing within components.
1. Use the `withRouter` higher-order component.
2. Use composition and render a `<Route>`
3. Use the `context`.
React Router is mostly a wrapper around the [`history`][1] library. `history` handles interaction with the browser's [`window.history`][2] for you with its browser and hash histories. It also provides a memory history which is useful for environments that don't have a global history. This is particularly useful in mobile app development (`react-native`) and unit testing with Node.
A `history` instance has two methods for navigating: `push` and `replace`. If you think of the `history` as an array of visited locations, `push` will add a new location to the array and `replace` will replace the current location in the array with the new one. Typically you will want to use the `push` method when you are navigating.
In earlier versions of React Router, you had to create your own `history` instance, but in v4 the `<BrowserRouter>`, `<HashRouter>`, and `<MemoryRouter>` components will create a browser, hash, and memory instances for you. React Router makes the properties and methods of the `history` instance associated with your router available through the context, under the `router` object.
### 1. Use the `withRouter` higher-order component
The `withRouter` higher-order component will inject the `history` object as a prop of the component. This allows you to access the `push` and `replace` methods without having to deal with the `context`.
<!-- language: lang-js -->
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
### 2. Use composition and render a `<Route>`
The `<Route>` component isn't just for matching locations. You can render a pathless route and **it will always match the current location**. The `<Route>` component passes the same props as `withRouter`, so you will be able to access the `history` methods through the `history` prop.
<!-- language: lang-js -->
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
### 3. Use the context*
**But you probably should not**
The last option is one that you should only use if you feel comfortable working with React's [context][3] model (React's Context API is stable as of v16).
<!-- language: lang-js -->
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1 and 2 are the simplest choices to implement, so for most use cases, they are your best bets.
[1]: https://github.com/ReactTraining/history
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Window/history
[3]: https://facebook.github.io/react/docs/context.html
[4]: https://facebook.github.io/react/docs/context.html#why-not-to-use-context
> **React Router v5.1.0 with hooks**
There is a new `useHistory` hook in React Router >5.1.0 if you are using React >16.8.0 and functional components.
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
> **React Router v4**
With v4 of React Router, there are three approaches that you can take to programmatic routing within components.
1. Use the `withRouter` higher-order component.
2. Use composition and render a `<Route>`
3. Use the `context`.
React Router is mostly a wrapper around the [`history`][1] library. `history` handles interaction with the browser's [`window.history`][2] for you with its browser and hash histories. It also provides a memory history which is useful for environments that don't have a global history. This is particularly useful in mobile app development (`react-native`) and unit testing with Node.
A `history` instance has two methods for navigating: `push` and `replace`. If you think of the `history` as an array of visited locations, `push` will add a new location to the array and `replace` will replace the current location in the array with the new one. Typically you will want to use the `push` method when you are navigating.
In earlier versions of React Router, you had to create your own `history` instance, but in v4 the `<BrowserRouter>`, `<HashRouter>`, and `<MemoryRouter>` components will create a browser, hash, and memory instances for you. React Router makes the properties and methods of the `history` instance associated with your router available through the context, under the `router` object.
### 1. Use the `withRouter` higher-order component
The `withRouter` higher-order component will inject the `history` object as a prop of the component. This allows you to access the `push` and `replace` methods without having to deal with the `context`.
<!-- language: lang-js -->
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
### 2. Use composition and render a `<Route>`
The `<Route>` component isn't just for matching locations. You can render a pathless route and **it will always match the current location**. The `<Route>` component passes the same props as `withRouter`, so you will be able to access the `history` methods through the `history` prop.
<!-- language: lang-js -->
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
### 3. Use the context*
**But you probably should not**
The last option is one that you should only use if you feel comfortable working with React's [context][3] model (React's Context API is stable as of v16).
<!-- language: lang-js -->
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1 and 2 are the simplest choices to implement, so for most use cases, they are your best bets.
[1]: https://github.com/ReactTraining/history
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Window/history
[3]: https://facebook.github.io/react/docs/context.html
[4]: https://facebook.github.io/react/docs/context.html#why-not-to-use-context