I couldn't wait and I jumped into using the latest alpha version of react-router
v4. The all-new <BrowserRouter/>
is great in keeping your UI in sync with the browser history, but how do I use it to navigate programmatically?
-
spik3s : note that the accepted answer is not working, but this one is: https://stackoverflow.com/a/43250939/1533892 -- might be helpful to readers to accept that one instead. Disclaimer: the working answer is mine : ) – Harlan T Wood Nov 16 '17 at 00:28
-
@HarlanTWood Thanks! Had no time to update my answer, thanks for chipping in. Already marked your answer as correct. – spik3s Nov 16 '17 at 00:43
-
Excellent, thanks : ) – Harlan T Wood Nov 16 '17 at 00:51
10 Answers
The router will add a history
object to your component in the props
hash. So in your component, simply do:
this.props.history.push('/mypath')
Here is a full example:
In App.js
:
import React from 'react'
import {BrowserRouter as Router, Route} from 'react-router-dom'
import Login from './Login'
export default class App extends React.Component {
render() {
return (
<Router>
<div>
<Route exact path='/login' component={Login} />
</div>
</Router>
)
}
}
In Login.js
:
import React, {PropTypes} from 'react'
export default class Login extends React.Component {
constructor(props) {
super(props)
this.handleLogin = this.handleLogin.bind(this)
}
handleLogin(event) {
event.preventDefault()
// do some login logic here, and if successful:
this.props.history.push(`/mypath`)
}
render() {
return (
<div>
<form onSubmit={this.handleLogin}>
<input type='submit' value='Login' />
</form>
</div>
)
}
}

- 2,064
- 21
- 19
-
1woow Thank you. This saves my day. Perfectly works with the latest release version of react and react-router – shrawan_lakhe May 05 '17 at 07:29
-
2throwing error `Cannot read property 'object' of undefined` , any hack for this ? – Pardeep Jain Oct 03 '17 at 07:55
-
@PardeepJain can you include the top few lines of a stacktrace, if any? – Harlan T Wood Oct 19 '17 at 00:05
-
This is more of an imperative method. You should just be using `Redirect` instead. It uses the same `Push` and `Replace` methods under the hood, but is more declarative – nikjohn Oct 04 '18 at 19:57
In the past you might have used browserHistory
to push a new path. This won't work with react-router
v4. Instead you have make use of React's context
and router
's transitionTo
method.
Here's a simple example:
import React from 'react';
class NavigateNext extends React.Component {
constructor() {
super();
this.navigateProgramatically = this.navigateProgramatically.bind(this);
}
navigateProgramatically(e) {
e.preventDefault();
this.context.router.transitionTo(e.target.href)
}
render() {
return (
<Link to={"/next-page"}
onClick={this.navigateProgramatically}
>Continue</Link>
);
}
}
NavigateNext.contextTypes = {
router: React.PropTypes.object
};
transitionTo
is just one of available router
methods. router
object also contains blockTransitions(getPromptMessage)
, createHref(to)
and replaceWith(loc)
which are worth checking out.
Here's official react-router
tutorial that mentions above method.
If you wanna learn more about using react
's context
check out the docs.

- 1,189
- 2
- 11
- 27
-
6I'm trying this out but router variable in context object is undefined. "Somehow" it is valid variable inside Link.js. Any idea how to get hold of router object outside of Link.js? – singularity Oct 19 '16 at 13:25
-
4I am using redux. How do I access the router object from an action creator ? – Kaidjin Feb 08 '17 at 09:39
-
9This did not work for me. I eventually figured out that everything you need is passed to your component in `props`! All you need is `this.props.history.push('/mypath')`. I gave a full example in a separate answer below: http://stackoverflow.com/a/43250939/1533892 – Harlan T Wood Apr 07 '17 at 22:16
-
@Kaidjin check [this](https://stackoverflow.com/a/46743951/2568259) for accessing history in **redux** **actions**. – patotoma Oct 14 '17 at 11:23
I don't have enough reputation to comment, but in answer to @singularity's question, you have to include the context properties you wish to make available on the component class' contextTypes
static property.
From the React docs on context
:
If contextTypes is not defined, then context will be an empty object.
In this case:
class NavigateNext extends React.Component {
// ...
static contextTypes = {
router: PropTypes.object
}
// ...
}
Unlike propTypes
, contextTypes
actually cause React to behave differently and is not only for typechecking.

- 185
- 1
- 5
-
Thank you for this point out. I was setting 'router' on propTypes instead of contextTypes. – Marek Apr 18 '17 at 11:23
-
thanks this is what is was missing. now i can use this.context.history.goBack() – tjones0808 Aug 22 '17 at 18:12
Using withRouter
will add router properties to you component, then you can access the history
and use push
like you did with v3:
import React from 'react';
import { withRouter } from 'react-router-dom';
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '',
};
this._submit = this._submit.bind(this);
}
render() {
return (
<form onSubmit={this._submit}>
<input type="text" onChange={(event) => this.setState({input: event.target.value})}/>
<button type="submit">Submit</button>
</form>
);
}
_submit(event) {
event.preventDefault();
this.props.history.push(`/theUrlYouWantToGoTo`);
}
}
export default withRouter(Form);

- 7,185
- 5
- 34
- 32
-
3Worked like a charm, to anyone that hates React Router just as much as me, this will work ;) – Francis Malloch May 11 '17 at 03:56
-
react-router v4 beta is released and the API changed a little bit. Instead of this.context.router.transitionTo(e.target.href)
Do, this.context.router.push(e.target.href)
if you are using latest version.
Link to new doc: https://reacttraining.com/react-router/#context.router

- 2,176
- 1
- 24
- 30
-
5I am using react-router-dom version 4.1.2 and the only way I got this working is with `this.context.router.history.push('/')`. Maybe this will help someone. – Marek Apr 18 '17 at 11:25
If you need to navigate outside of a component at a location that you are unable to pass in the history object from a component similar to how you would do with browserHistory in older versions you can do the following.
First create a history module
History.js:
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory();
Then when you are declaring the Router make sure to import Router from react-router and not react-router-dom (which is just a wrapper to react-router version but creates history object automatically) and pass in the history module you just created
Root.js (or wherever you do this):
import Router from 'react-router/Router'
import history from './history'
...
class Root extends Component{
render() {
return (
<Router history={history}>
...
</Router>
);
}
}
Now your application will use the custom created history you created. You can now import that history module anywhere and just do history.replace and so forth just like you would of done with browserHistory in the past.
SomeModule.js:
import history from './history';
export default ()=>{
// redirecting to login page using history without having to pass it in
// from a component
history.replace('/login')
}
Of course this is not the recommended way just as using browserHistory in the old versions was not the recommended way since things like server side rendering won't work, but if you don't care about that this can often be the right solution.
An extra benefit doing this is you could augment the history object to things lie parsed query string params like this for example:
import createBrowserHistory from 'history/createBrowserHistory'
import queryString from 'query-string';
const history = createBrowserHistory();
history.location.query = queryString.parse(history.location.search);
history.listen(() => {
history.location.query = queryString.parse(history.location.search);
});
export default history;

- 3,763
- 1
- 31
- 26
If you need to access history outside of components (for example in redux actions) react-router has published their original solution here.
Basically you have to create your own history object:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
And pass it to your router:
import { Router } from 'react-router-dom';
ReactDOM.render((
<Router history={history}> // <<-- the history object
<App/>
</Router>
), document.getElementById('root'))
Note: you have to use plain Router instead of BrowserRouter or HashRouter here!
If you export the history
now, you can work with it anywhere:
import history from './history';
history.push('/home');

- 1,069
- 2
- 11
- 15
-
will i be able to use withRouter HOC to access history after using this? like the doc says we will have to use this history object everywhere .. and will the location object be available with withRouter HOC after going forward with this ? – Rajiv Jul 21 '18 at 14:06
-
1
-
-
I found using state, a ternary operator and <Redirect>
worked best. I think this is also the prefered way since it is closest to the way v4 is set up.
In the constructor()
this.state = {
redirectTo: null
}
this.clickhandler = this.clickhandler.bind(this);
In the render()
render(){
return (
<div>
{ this.state.redirectTo ?
<Redirect to={{ pathname: this.state.redirectTo }} /> :
(
<div>
..
<button onClick={ this.clickhandler } />
..
</div>
)
}
In the clickhandler()
this.setState({ redirectTo: '/path/some/where' });
Hope it helps. Let me know.

- 755
- 4
- 8
-
1Using redirect doesn't navigate to a new state, but replaces the current state in the history, so you can't navigate back. – Mika Tähtinen Sep 06 '17 at 11:46
-
@MikaTähtinen That's just the default behavior. You can always set the `push` param to true so `push` is used instead of `replace` – nikjohn Oct 04 '18 at 20:01
use withRouter
:
import React, { PropTypes } from 'react'
import { withRouter } from 'react-router'
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
render() {
const { match, location, history } = this.props
return (
<div>You are now at {location.pathname}</div>
)
}
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)

- 34,501
- 19
- 112
- 166
It is really difficult with react-router. None of the options are straight-forward. this.props.history
gave me undefined
. But
window.location='/mypath/';
worked for me in version 5.0.0
. Don't know whether it is the right method.

- 3,829
- 25
- 35
-
This is a redirect in JavaScript and not really the right approach for a SPA – Adam Jun 09 '21 at 23:28