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

A more descriptive createElement warning #7402

Closed
wants to merge 10 commits into from
87 changes: 87 additions & 0 deletions docs/warnings/create-element-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: Invalid type for createElement
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s call it Invalid Element Type Warning for consistency with other warning’s style. Same for filename, would be invalid-element-type.md.

layout: single
permalink: warnings/create-element-types.html
---

You probably came to this page because of this error:

```
Warning: 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).
```

This usually occurs when attempting to render an element that is of an invalid type. The following examples will trigger this error:

Copy link

@jamesblight jamesblight Aug 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most people will come to this page from the link provided in the warning message. Assuming that is true, I think a more informative message could be shown here without repeating the warning.

Instead of:

You probably came to this page because of this error:

Warning: 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).

This usually occurs when attempting to render an element that is of an invalid type. The following examples will trigger this error:](url)

You could write something like:

You probably came here because your code is trying to create a ReactElement with an invalid type. This usually happens when you have an invalid import statement.

### Invalid types

Ensure that your component is not of the following types: undefined, boolean, number or null.

`Foo.js`

```js
let Foo;

if (false) {
Foo = () => <div />;
}

export default Foo; // Foo is undefined
```

`App.js`

```js
import Foo from './Foo'

class ReactApp extends Component {
render() {
return <Foo />;
}
}
```

### Invalid member imports

This happens when attempting to import a member as a default member, or importing a default member as a member.

`Foo.js`

```js
export const Foo = () => { return <div /> }
```

`App.js`

```js
import Foo from './Foo' // wrong!
// correct: import { Foo } from './Foo';

class ReactApp extends Component {
render() {
return <Foo />;
}
}
```

### Invalid or missing export

Check that the component is exported properly with the keyword `export`.

`Foo.js`

```js
const Foo = () => { return <div /> } // Foo needs to be exported
```

`App.js`

```js
import { Foo } from './Foo' // Foo is undefined

class ReactApp extends Component {
render() {
return <Foo />;
}
}
```
3 changes: 2 additions & 1 deletion src/isomorphic/classic/element/ReactElementValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ var ReactElementValidator = {
validType,
'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',
'(for composite components). See ' +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of just adding a link here, I would rather add a separate condition checking specifically for undefined and add a more descriptive message for that case. This is the case with most bundlers using Babel: you get undefined when you misspell an import.

'https://facebook.github.io/react/warning/create-element-types.html%s',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't read the actual proposal but assuming we move forward, 2 things:

  1. Please use a short url, we can hook that up later. Let's say fb.me/react-warning-create-element or something similar.
  2. The url should be the last thing in the message so we should have the %s before it.

Copy link
Author

@jin jin Aug 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 will do

getDeclarationErrorAddendum()
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,24 +297,28 @@ describe('ReactElementValidator', function() {
React.createElement(123);
expect(console.error.calls.count()).toBe(4);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: 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).'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html'
);
expect(console.error.calls.argsFor(1)[0]).toBe(
'Warning: 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).'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html'
);
expect(console.error.calls.argsFor(2)[0]).toBe(
'Warning: 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).'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html'
);
expect(console.error.calls.argsFor(3)[0]).toBe(
'Warning: 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).'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html'
);
React.createElement('div');
expect(console.error.calls.count()).toBe(4);
Expand All @@ -336,10 +340,11 @@ describe('ReactElementValidator', function() {
);
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: 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). Check the render method of ' +
'`ParentComp`.'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html ' +
'Check the render method of `ParentComp`.'
);
});

Expand Down Expand Up @@ -537,9 +542,10 @@ describe('ReactElementValidator', function() {
void <Foo>{[<div />]}</Foo>;
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: 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).'
'Warning: 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). See ' +
'https://facebook.github.io/react/warning/create-element-types.html'
);
});

Expand Down