remix-run / react-router

Declarative routing for React
https://reactrouter.com
MIT License
53.03k stars 10.31k forks source link

react-router 0.13.2 Uncaught TypeError: Cannot call a class as a function #1134

Closed krisskross closed 9 years ago

krisskross commented 9 years ago

Hi

I'm getting an error when trying to render this simple page with react 0.13.0 and react-router 0.13.2.

var React = require('react');
var Router = require('react-router');
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;

var App = React.createClass({
  render: function() {
    return (
      <div> </div>
    );
  }
});

var routes = (
  <Route handler={App} name="app" path="/">
  </Route>
);
Router.run(routes, function (Handler, state) {
  React.render(<Handler/>, document.getElementById('content'));
});

Chrome complains about the following line.

var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };

The page renders fine if I remove react-router. Any ideas of what could be wrong?

Cheers, -Kristoffer

flexd commented 9 years ago

I am also having this problem, just following the most basic example.

paulmillr commented 9 years ago

same shit here. 0.13.2 broke our app. We've rolled back to 0.12 for now

@rackt this is critical actually. React-router doesn't work at all currently.

flexd commented 9 years ago

I have somehow made it work with 0.13.2. No idea what I did, it just suddenly stopped giving me the error. :confused:

The example above works, with 0.13.2 and React 0.13.2

gaearon commented 9 years ago

Is there any chance you are using an old version of JSX transpiler that compiles <Handler /> into Handler() instead of the correct React.createElement(Handler)?

gaearon commented 9 years ago

@paulmillr

React-router doesn't work at all currently.

Can you please give the exact steps or a sample project to reproduce? RR 0.13.2 works for me (I'm testing with React 0.13 and Babel).

The issue seems definitely related to the tranpsiler in your project compiling JSX in the pre-0.12 style for some reason. I can reproduce it if I write Handler() manually.

gsanta commented 9 years ago

Same problem with react-router 0.13.3 and react 0.13.2.

gaearon commented 9 years ago

@gsanta What JSX transpiler are you using?

stowns commented 9 years ago

+1 using grunt-react

paulmillr commented 9 years ago

we're using CJSX compiler.

adjavaherian commented 9 years ago

Us too. Specifically in our test suite, we have a test context which handles each component. In the example below, targetComponent can be any old React Class. Problem seems to be isolated to TestLocation in our case.


// tests/TestContext.js
// used to bootstrap components that require flux
'use strict';

var Router = require('react-router'),
    Route = Router.Route,
    TestLocation = Router.TestLocation,
    FluxxorTestUtils = require('fluxxor-test-utils'),
    FluxConstructor = require('../../app/FluxConstructor.js');

var TestContext = {

    getRouterComponent: function(targetComponent, props) {
        var realFlux = FluxConstructor();
        var fakeFlux = FluxxorTestUtils.fakeFlux(realFlux);

        //check props and add flux
        if(typeof props === 'undefined'){
            props = {};
        }
        props.flux = fakeFlux;

        var component, mainComponent,
            routes = (
                <Route name="test" path="/" handler={targetComponent} />
            );

        //create router history
        TestLocation.history = ['/test'];

        //run router
        Router.run(routes, TestLocation, function (Handler) {

            //mainComponent = React.render(<Handler props={props} />, global.document.body);
            //component = TestUtils.findRenderedComponentWithType(mainComponent, targetComponent);

        });

        return {
            flux: fakeFlux,
            component: component,
            mainComponent: mainComponent,
            location: TestLocation
        };
    }
};

module.exports = TestContext;

Using └── babel@4.7.16 └── react-router@0.13.3

Trace:

1) app/modules/HeaderNav.jsx renders the HeaderNav class:
TypeError: Cannot call a class as a function
at _classCallCheck (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/locations/TestLocation.js:3:106)
at Function.TestLocation (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/locations/TestLocation.js:17:5)
at Function.dispatchHandler (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:381:22)
at /Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:349:29
at /Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/Transition.js:69:9
at Function.Transition.to (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/Transition.js:72:15)
at /Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:348:22
at Function.Transition.from (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/Transition.js:51:15)
at Function.dispatch (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:345:20)
at Function.refresh (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:396:16)
at Function.run (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/createRouter.js:392:16)
at Object.runRouter [as run] (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/runRouter.js:45:10)
at Object.getRouterComponent (/Users/4m1r/xxxxxx/xxxxxx-web/test/lib/TestContext.js:32:16)
at Context.<anonymous> (/Users/4m1r/xxxxxx/xxxxxx-web/test/app/modules/headerNav-test.js:26:62)
    at callFn (/usr/local/lib/node_modules/mocha/lib/runnable.js:266:21)
    at Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:259:7)
    at Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:387:10)
    at /usr/local/lib/node_modules/mocha/lib/runner.js:470:12
    at next (/usr/local/lib/node_modules/mocha/lib/runner.js:312:14)
    at /usr/local/lib/node_modules/mocha/lib/runner.js:322:7
    at next (/usr/local/lib/node_modules/mocha/lib/runner.js:257:23)
    at /usr/local/lib/node_modules/mocha/lib/runner.js:284:7
    at done (/usr/local/lib/node_modules/mocha/lib/runnable.js:222:5)
    at callFn (/usr/local/lib/node_modules/mocha/lib/runnable.js:277:7)
    at Hook.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:259:7)
    at next (/usr/local/lib/node_modules/mocha/lib/runner.js:268:10)
    at Object._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:289:5)
    at processImmediate [as _immediateCallback] (timers.js:354:15)

Aside from having to change to the exported TestLocation require, works fine in RR12.

gaearon commented 9 years ago

@paulmillr Do you use coffee-react >=3.0?

gaearon commented 9 years ago

To anybody having this problem: please, can you extract a reproducible example? It's hard to say what's going on because on my projects, and in examples, everything works fine. It's hard to guess by code snippets. It's even harder to guess without them.

gaearon commented 9 years ago

@adjavaherian

In your example, TestLocation is used incorrectly. It should be created individually for each test:

var location = new TestLocation([ '/test' ]);
Router.run(routes, location, function (Handler) {
  ...
});

It should not be used directly like in your example:

Router.run(routes, TestLocation, function (Handler) { // wrong

If the code that sets fields directly on TestLocation worked before, it was pure luck. It's true that the docs are lacking on it, please feel free to send a PR :-). Personally I think it might be better to export factories (createTestLocation and createStaticLocation) to prevent these kinds of mistakes. (cc @mjackson who's working on the new API)

adjavaherian commented 9 years ago

Thanks @gaearon that helps, so I no longer get the class issue, but now I'm seeing a makeHref issue.

        var component, mainComponent,
            routes = (
                <Route name="test" path="/test" handler={targetComponent} />
            );

        //create router history
        var location = new TestLocation(['/test']);

        //run router
        Router.run(routes, location, function (Handler) {
            mainComponent = React.render(<Handler props={props} />, global.document.body);
            component = TestUtils.findRenderedComponentWithType(mainComponent, targetComponent);

        });
     TypeError: Cannot call method 'makeHref' of undefined
      at Link.getHref (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/components/Link.js:74:34)
      at Link.render (/Users/4m1r/xxxxxx/xxxxxx-web/node_modules/react-router/lib/components/Link.js:99:20)

These warnings too

  app/modules/HeaderNav.jsx
Warning: Failed Context Types: Required context `router` was not specified in `Link`.
Warning: owner-based and parent-based contexts differ (values: `undefined` vs `function (props, context) {
      // This constructor is overridden by mocks. The argument is used
      // by mocks to assert on what gets mounted.

      if ("production" !== process.env.NODE_ENV) {
        ("production" !== process.env.NODE_ENV ? warning(
          this instanceof Constructor,
          'Something is calling a React component directly. Use a factory or ' +
          'JSX instead. See: http://fb.me/react-legacyfactory'
        ) : null);
      }

I haven't upgraded this to RR13 yet, but this repo shows the whole test suite I'm using, if you wanna try forking that and upgrading it to 13. https://github.com/adjavaherian/mocha-react

gaearon commented 9 years ago

@adjavaherian

This guide describes the contextTypes problem you're having, as well as the solution to it.

srolel commented 9 years ago

I'm having this issue as well.

React.CreateElement has this line:

return type.apply(null, Array.prototype.slice.call(arguments, 1));

Where type is require('react-router').Route, or the following function:

function Route() {
    _classCallCheck(this, Route);
    if (_React$Component != null) {
      _React$Component.apply(this, arguments);
    }
  }

the context of this call is clearly null, which makes _classCallCheck(this, Route); throw.

gaearon commented 9 years ago

React.CreateElement has this line: return type.apply(null, Array.prototype.slice.call(arguments, 1));

As far as I can see React 0.13 doesn't contain this line. On the other hand, React 0.12 contains it. Which is why the current version of the router requires React 0.13. Are you sure you're using it?

srolel commented 9 years ago

That did it, thanks! Not sure why I had an older version.

gaearon commented 9 years ago

If you have this issue you're either:

I'm closing this issue. If you have a reproducible example of this problem, please share it with us so we can take a look!

toshi0383 commented 9 years ago

How can I figure out which jsx compiler version I am using ? I have this issue reproduced right now. My package.json dependency:

  "dependencies": {
    "express": "~3.3.4",
    "reactify": "~0.14.0",
    "react": "0.13",
    "parse": "*",
    "react-router": "0.13.3",
    "uglify-js": "~2.4.15"
  }

This is generated code using browserify -t reactify

    var App = React.createClass({displayName: 'App',
      render: function() {
        return (
          React.DOM.div(null,
            NavigationBar(null),
            RouteHandler(null)
          )
        );
      }
    });

    var routes = (
      Route({name: "app", path: "/", handler: App},
        Route({name: "login", path: "/login", handler: LoginBox}), // ERROR
        Route({name: "signup", path: "/signup", handler: SignUpBox}),
        Route({name: "session", path: "/session", handler: EventBox}),
        DefaultRoute({handler: EventBox})
      )
    );
gaearon commented 9 years ago

@toshi0383 You are using a very old version of reactify. Switch to 1.x and you'll be fine.

toshi0383 commented 9 years ago

Thanks, it worked !

blainegarrett commented 8 years ago

I ran into the same issue while working through a node server + react-router example. In that case, server.js was calling node-jsx.install(). I was running 0.2 of node-jsx (from the isomorphic-react example). Upgrading to 0.13.3 fixed the issue.

A generic tl;dr to this issue is "upgrade your jsx transpiler".