Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{history} undefined #1455

Closed
terebentina opened this issue Jul 1, 2015 · 42 comments
Closed

{history} undefined #1455

terebentina opened this issue Jul 1, 2015 · 42 comments

Comments

@terebentina
Copy link

I am trying to follow the examples from 1.0.0-beta2 or even the readme.md from master.
If I do (in browser)

import {history} from 'react-router/lib/BrowserHistory';

React.render((
    <Router history={history}>
...

I get Uncaught Error: Invariant Violation: Server-side <Router>s need location, branch, params, and components props. Try using Router.run to get all the props you need
Turns out that history is undefined this way.
Even when I do

import BrowserHistory from 'react-router/lib/BrowserHistory';
React.render((
    <Router history={BrowserHistory}>
...

as other examples suggest, it doesn't work. I get
Warning: Failed propType: Invalid prophistorysupplied toRouter, expected instance ofHistory. Uncaught Error: Invariant Violation: A <Router> needs a valid Location

The only way I got it to work was with <Router history={new BrowserHistory()}> but this is definitely not in the examples.

Am I doing something wrong or are the docs outdated?

@Schniz
Copy link
Contributor

Schniz commented Jul 1, 2015

Are you using beta2 or the master branch? { history } isn't available yet in the npm package.

@terebentina
Copy link
Author

beta2 from npm. But I did look at the beta2 docs and they are incorrect: http://rackt.github.io/react-router/tags/v1.0.0-beta2.html

@Schniz
Copy link
Contributor

Schniz commented Jul 2, 2015

You are correct. They are incorrect. The PR that fixes that was merged to master. Meanwhile, you should initiate a new History object

@aldendaniels
Copy link

Looks like in beta3 the docs are still incorrect.

@aflanagan
Copy link

I'm running into this same error even after trying <Router history={new BrowserHistory()}> using beta3

This is the entirety of my routing/rendering. Anyone have any suggestions?

import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route } from 'react-router';
import BrowserHistory from 'react-router/lib/BrowserHistory'
import App from './app.jsx'
import Dashboard from './dashboard.jsx'

ReactDOM.render(
  <Router history={ new BrowserHistory() }>
    <Route path='/' component={ App }>
      <Route name='dashboard' path='/dashboard/:filter' component={ Dashboard } />
    </Route>
  </Router>,
  document.getElementById('main-content')
)

@BerkeleyTrue
Copy link

@aflanagan Using beta3 you just

// lower case history is already an instance of browser history
import { history } from 'react-router/lib/BrowserHistory';

// ...
ReactDOM.render(
  <Router history={ history }>
    <Route path='/' component={ App }>
      <Route name='dashboard' path='/dashboard/:filter' component={ Dashboard } />
    </Route>
  </Router>,
  document.getElementById('main-content')
)

This project is moving fast and you should rely more on the source than the docs.

@aflanagan
Copy link

@BerkeleyTrue I started with

import { history } from 'react-router/lib/BrowserHistory'

and got the same error @terebentina did in beta2. I tried instantiating BrowserHistory myself per @terebentina's suggestion, but am still getting the same error.

If I set a breakpoint at the createElement call for the Router I can see that _reactRouterLibBrowserHistory.history is the history prop that's being passed in.

console.log(_reactRouterLibBrowserHistory.history instanceof History) // false

The _reactRouterLibBrowserHistory.history object looks like this

{
  changeListeners: Array[0]
  getScrollPosition: getWindowScrollPosition() {
  handlePopState: () { [native code] }
  isSupported: true
  location: null,
  parseQueryString: (str, options)
 __proto__: BrowserHistory
}

@BerkeleyTrue
Copy link

@aflanagan Is there a reason you are sticking with beta2? If not then consider updating to beta3.

This project is moving fast and you should rely more on the source than the docs.

beta2 history module also only exports the class, no instances.

beta2 is way out of date, is missing a bunch of patches and does not follow docs very well.

@terebentina and @aflanagan The reason {history} is undefined is because the browserHistory module in beta2 only exports a class called BrowserHistory. So when you tried import { history } from 'react-router/lib/BrowserHistory'; you are trying to read a property that is undefined. Its the same as trying to do:

var history = require('react-router/lib/BrowserHistory').history;
// when the module is defined as

export.BrowserHistory = BrowserHistory;

This has since been fixed and this issue should be closed.

@aldendaniels
Copy link

@BerkeleyTrue, per my previous comment this issue still exists in beta3.

The beta3 docs show:

import { Router, Route } from 'react-router';
import BrowserHistory from 'react-router/lib/BrowserHistory';

React.render((
  <Router history={BrowserHistory}>
    <Route path="about" component={About}/>
    <Route path="dashboard" component={Dashboard}/>
  </Router>
), document.body);

But in reality (in beta 3), we need to do this:

import { Router, Route } from 'react-router';
import BrowserHistory from 'react-router/lib/BrowserHistory';

React.render((
  <Router history={new BrowserHistory()}>
    <Route path="about" component={About}/>
    <Route path="dashboard" component={Dashboard}/>
  </Router>
), document.body);

This issue should not be closed.

@aflanagan
Copy link

@BerkeleyTrue per my original comment I am using beta3 not beta2.

I'm running into this same error even after trying <Router history={new BrowserHistory()}> using beta3

Again, per my previous comment, regardless of whether I instantiate the BrowserHistory object myself
(new BrowserHistory()) or import the instance using

import { history } from 'react-router/lib/BrowserHistory'

the instanceof validation still fails

console.log(_reactRouterLibBrowserHistory.history instanceof History) // false

@aldendaniels any suggestions?

@BerkeleyTrue
Copy link

My apologies. My impression was that this issue was with beta2.

Which bundler are you using?

@aflanagan
Copy link

@BerkeleyTrue No problem. I'm using babelify/browserify.

One thing that I realized I did wrong when debugging this was checking the instance type of the history object. I realized in my comment above I was comparing it to the browser's History class.

However, If I import the History module from react-router

import History from 'react-router/lib/History'

and check the instance type at the point where createElement is being called for the Router then my instanceof check passes as expected.

console.log(_reactRouterLibBrowserHistory.history instanceof History) // true

So it's weird that in the prop validation that occurs inside the createElement call that this fails.

@BerkeleyTrue
Copy link

@aflanagan I have a theory. It could be that you have two instances of BrowserHistory (or History) Class. The one you import and the one react-router imports. In this case instanceof will fail. I'm not sure how you could verify this.

@BerkeleyTrue
Copy link

@aldendaniels Are you also using browserify?

@aflanagan
Copy link

@BerkeleyTrue I was just wondering that same thing. I'm not sure how to verify this either. If anyone has any thoughts on how to verify that please let me know.

@BerkeleyTrue
Copy link

You could try doing a global search in your bundler to see if the exports['default'] = BrowserHistory or exports['default'] = History Comes up more than once.

You could also try to use something like disc to get a visual layout of the modules in your bundle.

Or try getting a webpack version up and running and see if you have the same issue.

The first two are not sure fire as you could overlook a module pretty easily. The third takes more effort and time but if it turns out it does work then you know for sure this is the issue. here is my webpack config for reference.

@kjs3
Copy link

kjs3 commented Jul 19, 2015

@aflanagan I was running into the same problem as you and falling back to commonjs require syntax seems to have fixed it. This is working for me.

var history = require('react-router/lib/BrowserHistory').history;

So, maybe this is a Babel issue?

@aflanagan
Copy link

@kjs3 - yup, switching back to commonjs syntax fixed it for me as well. :/

Not sure whether this should stay open here or whether I should file an issue with babel. I still don't have a clear picture of what is causing the error, though, like @BerkeleyTrue mentioned above, I suspect that there are multiple instances of BrowserHistory being imported. I have not yet had a chance to test this theory out.

@aldendaniels
Copy link

@aflanagan, sorry I didn't get back.

In the current version of babel, babel seems to do the right thing (try it out) so it's interesting that CommonJS syntax is fixing this for you.

ES6 syntax does work for me... I'm using browserify/babelify:

import BrowserHistory from 'react-router/lib/BrowserHistory';
<Router history={new BrowserHistory()}>

Maybe try blowing away node_modules and re-installing? Also run npm dedupe to check for duplicate copies of ReactRouter getting imported by dependencies. I'm really grasping at straws here though.

@stefanmihoc
Copy link

Getting the same with beta3. Tried everything from here and I still get the same, with the difference that I cannot get it to work.

Warning: Failed propType: Invalid prop `history` supplied to `Router`, expected instance of `History`. Check the render method of `Provider`.
Uncaught Error: Invariant Violation: A <Router> needs a valid Location

If I log it before serving it to the Router, the oject looks ok

HashHistory {changeListeners: Array[0], location: null, queryKey: null}
  changeListeners: Array[1]
  getScrollPosition: getWindowScrollPosition() {...}
  handleHashChange: () { [native code] }
  location: Location
  parseQueryString: (str, options) {...}
  queryKey: null
  __proto__: HashHistory

I use ES6 syntax, latest from browserify, babelify, watchify, uglify, and no server (I run it by simply opening index.html in browser, as I am just building first a mock-up of the real application, with some UI, functionality and some routing around, for demo purposes; without the router everything works fine). Any other ideas? Thanks.

@BerkeleyTrue
Copy link

Seems like the common issue is the use of es6 modules and browserify. @stefanmihoc Can you try using commonjs require for history?

@stefanmihoc
Copy link

Like I mentioned in my previous comment I tried everything above, and also everything mentioned in similar raised issues that are related to this. require with or without .default, requiring/importing HashHistory and new-ing it, requiring/importing already constructed history directly etc.

Any suggestions?...

@stefanmihoc
Copy link

Ok, so I have just found the culprit. The problem was indeed at bundling with browserify.
So, I have in my app the imports like this:

import { Router, Route, Link } from 'react-router';
import { history } from 'react-router/lib/HashHistory';

but I was using this kind of scripts to build the dependencies separately from the app (as watching a combined build with watchify would have been very slow):

  "scripts": {
    "builddep": "browserify -r classnames -r material-ui -r react -r react-redux -r react-router -r react-tap-event-plugin -r redux -r whatwg-fetch | uglifyjs -cm > lib/dependencies_bundle.js",
    "buildsrc": "browserify . -x classnames -x material-ui -x react -x react-redux -x react-router -x react-tap-event-plugin -x redux -x whatwg-fetch | uglifyjs -cm > lib/main.js",
    "watchsrc": "watchify . -x classnames -x material-ui -x react -x react-redux -x react-router -x react-tap-event-plugin -x redux -x whatwg-fetch -o lib/main.js -v -d",
    "test": "jest"
  },
  "browserify": {
    "transform": [
      [
        "babelify",
        {
          "stage": 0
        }
      ]
    ]
  }

So what was missing was the explicit requiring of react-router/lib/HashHistory in these scripts, like this:

    "builddep": "browserify -r classnames -r material-ui -r react -r react-redux -r react-router -r react-router/lib/HashHistory -r react-tap-event-plugin -r redux -r whatwg-fetch | uglifyjs -cm > lib/dependencies_bundle.js",
    "buildsrc": "browserify . -x classnames -x material-ui -x react -x react-redux -x react-router -x react-router/lib/HashHistory -x react-tap-event-plugin -x redux -x whatwg-fetch | uglifyjs -cm > lib/main.js",
    "watchsrc": "watchify . -x classnames -x material-ui -x react -x react-redux -x react-router -x react-router/lib/HashHistory -x react-tap-event-plugin -x redux -x whatwg-fetch -o lib/main.js -v -d",

If bundling like this (all scripts, app&dependencies, together):

    "buildsrcwithdep": "browserify . | uglifyjs -cm > lib/main.js",
    "watchsrcwithdep": "watchify . -o lib/main.js -v -d",

there are no problems.

@eXtreme
Copy link

eXtreme commented Aug 13, 2015

@stefanmihoc that's a great hint! I use babelify via gulp tasks and I generate separate vendors.js based on package.json like this:

var dependencies = Object.keys(packageJson && packageJson.dependencies || {});

I had to manually add this line below:

dependencies.push('react-router/lib/HashHistory');

and it works. Strange thing.

@knowbody
Copy link
Contributor

knowbody commented Sep 7, 2015

I have the same problem, I get this error:
Module not found: Error: Cannot resolve module 'react-router/lib/HashHistory'
I can't find HashHistory and BrowserHistory anywhere in the project. Anyone has a solution for that?

@gaearon
Copy link
Contributor

gaearon commented Sep 7, 2015

@knowbody

It's gone in 1.0.0-beta4.

Now you get hash history by default (no need to specify it).
If you want the pushstate history, do this:

import { createHistory } from 'history'; // you need to install this package
let history = createHistory();

@knowbody
Copy link
Contributor

knowbody commented Sep 7, 2015

ok got it, just realised that after removing the old: 'react-router/lib/HashHistory' it still kept the history. Need to read more source code in the future. thanks @gaearon

we definitely need to have this in the docs somewhere

@ryanflorence
Copy link
Member

sorry for the churn folks, docs are getting better as we approach 1.0 release. Hang in there.

@98percentoats
Copy link

Hey @knowbody Trying to get history into my react-router set-up to prevent the links outside of history errors, is this along the right lines if I'm not writing this the ES6 way?

var history = require('history/lib/createBrowserHistory').createHistory;

and then...

React.render((
    <Router history="{history}">
        <Route path="/"     component={HomeController}/>
        <Route path="about" component={AboutController}/>
        <Route path="blog"  component={BlogController}/>
        <Route path="work"  component={WorkController}/>
        <Route path="*"     component={NotFoundController}/>
    </Router>
), site);

I've done as much reading around as I can but this issue is probably the closest I've come to finding a solution.

@98percentoats
Copy link

@knowbody You sir, are a gentleman. tips hat

@knowbody
Copy link
Contributor

@davetgreen sorry I was wrong 😄

like this:

var createBrowserHistory = require('history/lib/createBrowserHistory');

<Router history={createBrowserHistory()} >...<Router />

@98percentoats
Copy link

@knowbody Thanks! Now I get the history object but I'm getting TypeError: history.listen is not a function. If it's beyond the scope of this issue I'll research it myself. 👍

@knowbody
Copy link
Contributor

not sure where that happens. try to look at the current issues, if there is nothing then create a new issue

@digitalmaster
Copy link

FYI: The readme example still says this import { Router, Route, Link, browserHistory } from 'react-router' .. Which is obviously wrong.

@taion
Copy link
Contributor

taion commented Jan 21, 2016

The readme example is against 2.0.0-RC, for which that syntax is absolutely correct.

@digitalmaster
Copy link

Gotcha.. i just did the standard npm install.. which installed v^1.0.3. Had no idea that the readme was for 2.0. Makes sense now tho thanks.

@fwon
Copy link

fwon commented Jan 24, 2016

Please update the readme file!

@wayspurrchen
Copy link

+1. This sent me down a bit of a rabbit hole. It seems unconventional that master is pointed to a version that isn't installed via npm, so a more explicit warning about what version master is on would probably be really helpful.

@digitalmaster
Copy link

@wayspurrchen yea.. never seen this issue before. Shouldn't the README for 2.x beta branch be on 2.x branch and not master?

@timdorr
Copy link
Member

timdorr commented Jan 25, 2016

In most git repos, master is the latest version of the code, including any in progress, unreleased bits. It's generally where all active development is happening, so the code there may be unstable. But you come here to see what is being developed, that is the whole point of Github. We, unfortunately, do not have a separate website for the project. If we did, I think this would end up being a lot clearer. I want to get that going shortly, since we get daily issues related to mismatched docs.

@digitalmaster
Copy link

@timdorr That makes a ton of sense. I think the reason this hasn't been an issue on other project docs is in fact because their documentation is external.

@wayspurrchen
Copy link

Cool, @timdorr, thank you for the clarification. :)

@lock lock bot locked as resolved and limited conversation to collaborators Jan 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests