-
Notifications
You must be signed in to change notification settings - Fork 47.3k
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
A more descriptive createElement warning #7402
Changes from all commits
3d1187e
b9dba9e
e782ed5
914f535
c08f81d
037818b
d01e2eb
3662819
6390b8d
056666d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
--- | ||
title: Invalid Element Type Warning | ||
layout: single | ||
permalink: warnings/invalid-element-type.html | ||
--- | ||
|
||
You probably came here because your code is trying to create a ReactElement with an invalid type using JSX or the `React.createElement` API. This usually happens when you have an invalid import statement. | ||
|
||
`React.createElement` requires an argument of type `string` (e.g. 'div', 'span'), or a `ReactClass`/`React.Component`. It cannot be of type `number`, `boolean`, `undefined` or `null`. See the documentation of this API: [https://facebook.github.io/react/docs/top-level-api.html](https://facebook.github.io/react/docs/top-level-api.html) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's also avoid saying ReactClass/React.Component here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which API are you referring to? It would make sense to link to createElement() specifically. You can hover over its header in docs to see the exact anchor link. Please also remove domain from the URL and just start it with /react. This is useful in case docs move. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was referring to the |
||
|
||
The following common examples will trigger this error: | ||
|
||
### Invalid types | ||
|
||
Ensure that your component is not of the following types: undefined, boolean, number or null. | ||
|
||
`Components.js` | ||
|
||
```js | ||
let Foo, Bar; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's avoid let here and use var so people don't think this warning is somehow related to let. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also let's avoid Foo and Bar and use something more realistic like Button. |
||
|
||
if (false) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not clear why you have if (false). Could you come up with a more realistic example please? |
||
Foo = () => <div />; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. People reading this might not understand arrow functions. I would avoid them here. |
||
} | ||
|
||
Bar = React.createElement(42); | ||
// The following types are invalid, too. | ||
// Bar = 42; | ||
// Bar = null; | ||
// Bar = undefined; | ||
// Bar = true; | ||
|
||
export { Foo, Bar }; // Foo is undefined and Bar is an invalid element. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would somebody want to export an element from a file? This looks confusing. |
||
``` | ||
|
||
`App.js` | ||
|
||
```js | ||
import { Foo, Bar } from './Components' | ||
|
||
class ReactApp extends Component { | ||
render() { | ||
return <Foo />; // or return <Bar /> | ||
} | ||
} | ||
``` | ||
|
||
### Invalid member imports | ||
|
||
This happens when attempting to import a member as a default member, or importing a default member as a member. | ||
|
||
`Components.js` | ||
|
||
```js | ||
export const Foo = () => { return <div /> } | ||
``` | ||
|
||
`App.js` | ||
|
||
```js | ||
import Foo from './Components' // wrong! | ||
// correct: import { Foo } from './Components'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. People will misunderstand this and think curly braces are always necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe just add a |
||
|
||
class ReactApp extends Component { | ||
render() { | ||
return <Foo />; | ||
} | ||
} | ||
``` | ||
|
||
### Invalid or missing export | ||
|
||
Check that the component is exported properly with the keyword `export`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. People might be using CommonJS so this is not always the case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "or your module system's export mechanism"? The documentation either has to pick a canonical modules system, or it'd need use cases for ES6, commonjs, AMD... |
||
|
||
`Components.js` | ||
|
||
```js | ||
const Foo = () => { return <div /> } // Foo needs to be exported | ||
``` | ||
|
||
`App.js` | ||
|
||
```js | ||
import { Foo } from './Components' // Foo is undefined | ||
|
||
class ReactApp extends Component { | ||
render() { | ||
return <Foo />; | ||
} | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -180,21 +180,37 @@ function validatePropTypes(element) { | |
} | ||
} | ||
|
||
function warnInvalidType(inputValue) { | ||
if (inputValue === undefined) { | ||
warning( | ||
false, | ||
'React.createElement: undefined is an invalid element type. ' + | ||
'Did you mistype an import or forget to export your component? ' + | ||
'It should be a string (for DOM elements), component ' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary extra indentation here and below. Let's keep lines aligned. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is useful, let's keep it. |
||
'class or function (for user-defined components).' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add "a" before "component class" and before "function". |
||
'%s See https://fb.me/react-invalid-element-type for more information.', | ||
getDeclarationErrorAddendum() | ||
); | ||
} else { | ||
warning( | ||
false, | ||
'React.createElement: %s is an invalid element type. ' + | ||
'It should be a string (for DOM elements), component ' + | ||
'class or function (for user-defined components).' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
'%s See https://fb.me/react-invalid-element-type for more information.', | ||
inputValue, | ||
getDeclarationErrorAddendum() | ||
); | ||
} | ||
} | ||
|
||
var ReactElementValidator = { | ||
|
||
createElement: function(type, props, children) { | ||
var validType = typeof type === 'string' || typeof type === 'function' || | ||
(type !== null && typeof type === 'object'); | ||
// We warn in this case but don't throw. We expect the element creation to | ||
// succeed and there will likely be errors in render. | ||
if (!validType) { | ||
warning( | ||
false, | ||
'React.createElement: type should not be null, undefined, boolean, or ' + | ||
'number. It should be a string (for DOM elements) or a ReactClass ' + | ||
'(for composite components).%s', | ||
getDeclarationErrorAddendum() | ||
); | ||
warnInvalidType(type); | ||
} | ||
|
||
var element = ReactElement.createElement.apply(this, arguments); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last sentence is only true if you have undefined type.