Skip to content

Commit c44c2a2

Browse files
DCtheTallgaearon
authored andcommitted
More helpful message when passing an element to createElement() (#13131)
* [#13130] Add a more helpful message when passing an element to createElement() * better conditional flow * update after review * move last condition inside last else clause * Added test case * compare 25132typeof to REACT_ELEMENT_TYPE * runs prettier * remove unrelated changes * Tweak the message
1 parent 28cd494 commit c44c2a2

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

packages/react/src/ReactElementValidator.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
getIteratorFn,
2020
REACT_FORWARD_REF_TYPE,
2121
REACT_FRAGMENT_TYPE,
22+
REACT_ELEMENT_TYPE,
2223
} from 'shared/ReactSymbols';
2324
import checkPropTypes from 'prop-types/checkPropTypes';
2425
import warning from 'shared/warning';
@@ -286,6 +287,10 @@ export function createElementWithValidation(type, props, children) {
286287
typeString = 'null';
287288
} else if (Array.isArray(type)) {
288289
typeString = 'array';
290+
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
291+
typeString = `<${getComponentName(type.type) || 'Unknown'} />`;
292+
info =
293+
' Did you accidentally export a JSX literal instead of a component?';
289294
} else {
290295
typeString = typeof type;
291296
}

packages/react/src/__tests__/ReactElementValidator-test.internal.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,17 @@ describe('ReactElementValidator', () => {
229229
});
230230

231231
it('gives a helpful error when passing invalid types', () => {
232+
function Foo() {}
232233
expect(() => {
233234
React.createElement(undefined);
234235
React.createElement(null);
235236
React.createElement(true);
236237
React.createElement({x: 17});
237238
React.createElement({});
239+
React.createElement(React.createElement('div'));
240+
React.createElement(React.createElement(Foo));
241+
React.createElement(React.createElement(React.createContext().Consumer));
242+
React.createElement({$$typeof: 'non-react-thing'});
238243
}).toWarnDev(
239244
[
240245
'Warning: React.createElement: type is invalid -- expected a string ' +
@@ -256,6 +261,21 @@ describe('ReactElementValidator', () => {
256261
'components) but got: object. You likely forgot to export your ' +
257262
"component from the file it's defined in, or you might have mixed up " +
258263
'default and named imports.',
264+
'Warning: React.createElement: type is invalid -- expected a string ' +
265+
'(for built-in components) or a class/function (for composite ' +
266+
'components) but got: <div />. Did you accidentally export a JSX literal ' +
267+
'instead of a component?',
268+
'Warning: React.createElement: type is invalid -- expected a string ' +
269+
'(for built-in components) or a class/function (for composite ' +
270+
'components) but got: <Foo />. Did you accidentally export a JSX literal ' +
271+
'instead of a component?',
272+
'Warning: React.createElement: type is invalid -- expected a string ' +
273+
'(for built-in components) or a class/function (for composite ' +
274+
'components) but got: <Context.Consumer />. Did you accidentally ' +
275+
'export a JSX literal instead of a component?',
276+
'Warning: React.createElement: type is invalid -- expected a string ' +
277+
'(for built-in components) or a class/function (for composite ' +
278+
'components) but got: object.',
259279
],
260280
{withoutStack: true},
261281
);

0 commit comments

Comments
 (0)