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)
@timdorr IMO the problem with the documentation is that none of it is clear to understand or use
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:
browserHistorywon’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>.browserHistoryis not exposed by react-router in v4, only in v2.If you want the full
historyobject you can also grab that off context likerouter.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
withRouterto 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:
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-domandreact-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:
react-router)docsfolder on thereact-routerrepoguidesfolder on the repo (which, you know, newbies like me tend to be attracted to)apifolderhistory.mdto find not-too-helpful readmeRouter.mdfileJust then (and fighting the urge to read only the code blocks) I found:
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 injecthistory. 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
BrowserRoutercomponent. so the only way is to grab it off context. Some similar discussions in this issue: #4005