react-router: history.push not working when using BrowserRouter

startup file

import {BrowserRouter} from 'react-router';
let root=<BrowserRouter>
                     //Some components
              </BrowserRouter>
 ReactDOM.render(Root, document.getElementById("app"))

function to navigate or route

import createBrowserHistory from 'history lib createBrowserHistor';
const history = createBrowserHistory();
let browseTo=function(somepath){
           history.push({pathname: somepath})
})

After calling above Function only URL path changing actual route is not perform. Like URL localhost:8080 changes to localhost:8080/login not routing to login component.

Also tried

import { browserHistory } from './react-router'
let browseTo=function(somepath){
          browserHistory.push('/some/path')
}

but have error browserHistory is undefined

If i use this.context.router.transitionTo('/Some/Path') its working but it is not proper solution

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 5
  • Comments: 30 (7 by maintainers)

Most upvoted comments

@timdorr IMO the problem with the documentation is that none of it is clear to understand or use

  • It feels like almost no examples show what’s been imported/exported
  • All examples are all written as though it’s a single file in context when in real world cases you’re not in a single file
  • Some examples don’t make sense, they have classes with just jsx beneath it or objects that aren’t clear what they are for or how they are received/obtained
  • Everything is written at a level that seems to assume that you already understand everything that it’s telling you - that’s not very beginner friendly

I’ve so far spent the past month in my spare time trying to understand v4 router and it feels ridiculously hard if not impossible to get my head around. The documentation seems to be trying to be minimalist and comes across as though whoever wrote it didn’t have much consideration for anyone starting out with this.

All and all, this is just extremely hard for any beginner/intermediate to understand or attempt to implement - quite aside from the fact that it’s so different to the previous implementations.

Just look at the code: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

No magic. It’s just one line to create a history instance and then it wraps <Router>.

So it looks like you’re trying to mix and match react-router v2 and v4, which are very different.

A couple of points:

  1. Creating a new browserHistory won’t work because <BrowserRouter> creates its own history instance, and listens for changes on that. So a different instance will change the url but not update the <BrowserRouter>.
  2. browserHistory is not exposed by react-router in v4, only in v2.

If you want the full history object you can also grab that off context like router.

this.context.history.push('/path')

I’m trying to keep old, closed issues from being revived. I don’t want to lock things completely, but this issue (amongst many others) needs to die 🔪

If you have an issue with the documentation, just saying “they suck” isn’t going to do anything. Specific criticisms help, but even better is a PR to fix those issues. We are always open to improving our documentation. I maintain Redux and it’s claim-to-fame is great, community-built documentation.

By all means, go here and take a crack at it. We want it to get better, but need specific guidance on what is not working.

@timdorr The problem with killing threads like this is that new coders are running into this problem still, and the documentation either doesn’t do a good job describing how to use it, or isn’t documented well enough to be easy to find for non-experts. This is a required, dependent API, yet it’s very complicated in its use. One potential issue is that the tutorials that came out earlier this year on react are using the older version, but people want to use the newer version (like myself).

I just spent 3 hours on this issue, and finally found someone that told me I can use this.props.history… go figure.

Define a history instance yourself and then pass it into a plain <Router>. You can use that history as a singleton or pass it around however you need to.

You can also you withRouter to get an history in your props

@timdorr agreed on the issue killing, but after 3 full days trying to understand what was wrong with my code (react newbie here, I admit) this line saved my life:

You should use <Router history={history}>. The preconfigured routers ignore the history prop.

So kill the issues, but please, PLEASE, expand on the docs when something gets tricky (everyone was used to get history in other ways and everyone, and I do mean all the blog posts on the whole internet, is pointing this use case wrong)

Anyways, thanks a lot for your time and effort, it sure was driving me mad

I feel I need to further explain my particular confusion with the docs. Because (it must be said) docs are fine. Really.

I just feel that a bigger heads up regarding history should be included. The guides are really nice, I just missed the difference between react-router-dom and react-router, but the particular .md (which I failed to find) was quite clarifying (after having found this very issue/comment/thread).

Hence, I believe, the issue is that in order to find this clarifying doc I had to:

  • find the repo
  • ignore the beautiful link to docs (which leads to another site, so the rest of the docs on github remain ignored)
  • follow the link to Router (react-router)
  • find nothing too useful on the main readme (regarding history)
  • check the docs folder on the react-router repo
  • check guides folder on the repo (which, you know, newbies like me tend to be attracted to)
  • go back to realize there’s an api folder
  • check on the history.md to find not-too-helpful readme
  • go back and (finally) check the Router.md file

Just then (and fighting the urge to read only the code blocks) I found:

The most common use-case for using the low-level <Router> is to synchronize a custom history with a state management lib like Redux or Mobx. Note that this is not required to use state management libs alongside React Router, it’s only for deep integration.

As I said, the docs are really fine. Seems to me that being this such a tricky way to cope with the history issue, it should be pointed out more strongly.

So, all that said, I also want to show some love for the contributors and commiters, this library is fantastic and I wouldn’t have achieved what I needed without it. I just feel the clarifying paragraph should be pointed out more strongly, or maybe even stated somewhere more findable (higher on the docs tree?)

Hope this helps whoever comes next with some similar issue. Love you guys.

@Izhaki You should use <Router history={history}>. The preconfigured routers ignore the history prop.

In our app, we navigate programmatically via a redux middleware that uses history.

The prime reason for this is that we need to log navigation actions for audit trail purposes.

So we inject history to the store/middleware. Note that the store (<Provider>) is the parent of the router.

Now in V4 <BrowserRouter> derives from <Router> to which you can inject history. This seems to work:

<BrowserRouter history={ history }>

Am I missing something?

Using context its working but I am navigating through custom browseTo library function. then need to pass current context as a parameter to function every time. Is there another approach without context

@joaoreynolds Well, I feel silly, but your mock suggestion works very well, thanks.

@timdorr The issue with this is that <Router> doesn’t quite lends itself to tests with frameworks like JSDOM.

Not at the moment, the history instance is internal to the BrowserRouter component. so the only way is to grab it off context. Some similar discussions in this issue: #4005