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

Confusing error message when passing non string, non component class to React.createElement #3478

Closed
andreypopp opened this issue Mar 22, 2015 · 29 comments · Fixed by #3521
Closed

Comments

@andreypopp
Copy link
Contributor

The following code:

var X = true;
var Hello = React.createClass({
    render: function() {
        return <X>Hello {this.props.name}</X>;
    }
});

produces

Uncaught TypeError: undefined is not a function

deep into React.

http://jsfiddle.net/92env5pj/1/

@zpao
Copy link
Member

zpao commented Mar 24, 2015

Yea, we can do better than that. On the plus side, looks like this error will actually log as TypeError: type.toUpperCase is not a function in the near future (does for me in my browsers: Firefox Nightly, Chrome beta).

We should be able to catch this in createElement. Strings are ok. Functions are ok (I think, or will be). Objects with certain characteristics are ok (has a render function?)

@sophiebits
Copy link
Collaborator

No objects, just functions that return objects with a render function. I thought we had a warning for this already though.

@zpao
Copy link
Member

zpao commented Mar 24, 2015

@grant
Copy link
Contributor

grant commented Mar 26, 2015

Sorry for all the references above. Let me know how this PR looks.

jimfb added a commit that referenced this issue Mar 26, 2015
Display error when trying to create an element of type `boolean`. Fixes #3478
@kdamball
Copy link

I'm still getting this error (I just installed the latest react version). Any ideas why it happens? Everything else bundles rather alright with browserify but the main client script doesn't run and flags with this error.

@tomef
Copy link

tomef commented May 27, 2015

@kdamball It's a long shot, but I just had the same error, and it turned out to be a component that I was including with require further up the component hierarchy than it was actually being used. Once I removed the extra require it ran just fine again.

If it helps to narrow down the component, the hierarchy was Ancestor > ChildList > Child > ChildList > Child... (recursive). The Ancestor component was unnecessarily including the Child component.

But again this is pure speculation since the error message was in no way indicative of the solution I found, so the problem in your case may be completely different :) Cheers

@kdamball
Copy link

@bodjkin Yep, you are right, it was totally my own error. The error reporting should be better though. It seems like frontend scripts are better at this than bundling everything using browserify.

@cosmith
Copy link

cosmith commented Jun 6, 2015

Thanks @bodjkin, you saved me a lot of time ;) I had simply forgotten to add the module.exports = ... on a react component. I agree that this error is pretty confusing, even with the TypeError: type.toUpperCase is not a function message (which is what I got).

@johntyree
Copy link

I just had the same issue that cosmith had. The TypeError really isn't very helpful. The real error is only tangentially related to types...

@sophiebits
Copy link
Collaborator

@cosmith @johntyree Did you see a warning in the console logged before the exception was thrown? There should be one.

React.createElement: type should not be null or undefined. It should be a string (for DOM elements) or a ReactClass (for composite components).

@johntyree
Copy link

@spicyj good question. It was probably there, but I don't recall now. Why would that be a warning and not an exception itself?

@sophiebits
Copy link
Collaborator

For this case specifically, it's because we want to be able to inline calls to React.createElement (#3228) without changing runtime behavior which we can do only if createElement never throws.

@johntyree
Copy link

Can it be made to only throw when not in production? Granted, even I don't like that idea very much...

I'm not sure there's a better solution than just emitting a warning before everything explodes. At the end of the day the dev is just going to Google the error because it's completely opaque. Then they'll find this thread or something similar and move on with their lives.

@infolock
Copy link

Not sure if this will help someone in the future, but another way to get this same error ( Uncaught TypeError: type.toUppercase is not a function) is by referencing a component that hasn't been added to module exports.

So this will throw the error mentioned:

const React = require( 'react' );
class MyComponent extends React.Component {
  //.... 
}

This will fix it:

const React = require( 'react' );
class MyComponent extends React.Component {
  //.... 
}

module.exports = MyComponent;

@sophiebits
Copy link
Collaborator

Hopefully we can make the toUpperCase error a little less cryptic. Just posted #4154.

sophiebits added a commit that referenced this issue Jun 17, 2015
Improve error message when mounting non-string/function elements
@infolock
Copy link

very nice 👍

@ibrahim12
Copy link

I was trying to do React.renderToString(<Element />) and was getting this error.
Later found that, Element has inline css display:none entry at its root

. After Removing the entry it has been fixed.

@runrevben
Copy link

I'm struggling with this error too. Any pointers?

Here is my main app:

var React = require('react');
var TestComponent = require('./components/TestComponent.jsx');
React.render(<TestComponent />, document.getElementById('id'));

And here is my testcomponent.jsx:

var React = require('react');

var TestComponent = React.createClass({
  render: function() {
    return (
      <h1>asdfasdf</h1>
    );
  }
});

module.export = TestComponent;

I'm using the latest version of rect, reactify and browserify to compile

@ibrahim12
Copy link

@runrevben In your testcomponent.jsx file check the exports line , there is a typo I guess, It should be module.exports=TestComponent;

@runrevben
Copy link

@ibrahim12 Thank you! You saved me much frustration :)

@faria
Copy link

faria commented Jul 2, 2015

@infolock Thank you, that was the source of my bug too.

@kimchicharlie
Copy link

I had the same error trying to include a component inside the same component

var Foo = require('./foo.jsx');
var Bar = require('./main.jsx');

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

module.exports = Main;

Error :

TypeError: type.toUpperCase is not a function

@sophiebits
Copy link
Collaborator

In 0.14, you'll get something like this message:

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: null.

@tleunen
Copy link

tleunen commented Aug 10, 2015

hey @spicyj, kinda late on this, but would it be possible to get the name of the invalid component?
Let's say I try to use <MyComponent /> but MyComponent is wrong. Would it be possible to say that it's MyComponent that is failing the test?

Would help finding and fixing the errors

@sophiebits
Copy link
Collaborator

This isn't possible without changing the transform, no. You can look at the stack trace to see where the error was.

@Duan112358
Copy link

the error is so confused, and difficult to trace the error

@sophiebits
Copy link
Collaborator

Folks, I already made the error message better in 0.14. Please stop commenting.

@Duan112358
Copy link

👍

@ccorcos
Copy link

ccorcos commented Sep 29, 2015

@infolock Thank you do much!

Not sure if this will help someone in the future, but another way to get this same error ( Uncaught TypeError: type.toUppercase is not a function) is by referencing a component that hasn't been added to module exports.

What a terrible error message!

@facebook facebook locked and limited conversation to collaborators Sep 29, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.