Skip to content

Commit 86914cb

Browse files
HeroProtagonistgaearon
authored andcommitted
Clearer ssr error message 11902 (#11966)
* Match error message to one in `ReactFiber.js` * Add undefined/null guard and tests * Update tests and element check * Remove beforeEach block
1 parent f828ca4 commit 86914cb

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,5 +871,71 @@ describe('ReactDOMServerIntegration', () => {
871871
: ''),
872872
);
873873
});
874+
875+
describe('badly-typed elements', function() {
876+
itThrowsWhenRendering(
877+
'object',
878+
async render => {
879+
let EmptyComponent = {};
880+
expect(() => {
881+
EmptyComponent = <EmptyComponent />;
882+
}).toWarnDev(
883+
'Warning: React.createElement: type is invalid -- expected a string ' +
884+
'(for built-in components) or a class/function (for composite ' +
885+
'components) but got: object. You likely forgot to export your ' +
886+
"component from the file it's defined in, or you might have mixed up " +
887+
'default and named imports.',
888+
);
889+
await render(EmptyComponent);
890+
},
891+
'Element type is invalid: expected a string (for built-in components) or a class/function ' +
892+
'(for composite components) but got: object.' +
893+
(__DEV__
894+
? " You likely forgot to export your component from the file it's defined in, " +
895+
'or you might have mixed up default and named imports.'
896+
: ''),
897+
);
898+
899+
itThrowsWhenRendering(
900+
'null',
901+
async render => {
902+
let NullComponent = null;
903+
expect(() => {
904+
NullComponent = <NullComponent />;
905+
}).toWarnDev(
906+
'Warning: React.createElement: type is invalid -- expected a string ' +
907+
'(for built-in components) or a class/function (for composite ' +
908+
'components) but got: null.',
909+
);
910+
await render(NullComponent);
911+
},
912+
'Element type is invalid: expected a string (for built-in components) or a class/function ' +
913+
'(for composite components) but got: null',
914+
);
915+
916+
itThrowsWhenRendering(
917+
'undefined',
918+
async render => {
919+
let UndefinedComponent = undefined;
920+
expect(() => {
921+
UndefinedComponent = <UndefinedComponent />;
922+
}).toWarnDev(
923+
'Warning: React.createElement: type is invalid -- expected a string ' +
924+
'(for built-in components) or a class/function (for composite ' +
925+
'components) but got: undefined. You likely forgot to export your ' +
926+
"component from the file it's defined in, or you might have mixed up " +
927+
'default and named imports.',
928+
);
929+
930+
await render(UndefinedComponent);
931+
},
932+
'Element type is invalid: expected a string (for built-in components) or a class/function ' +
933+
'(for composite components) but got: undefined.' +
934+
(__DEV__
935+
? " You likely forgot to export your component from the file it's defined in, " +
936+
'or you might have mixed up default and named imports.'
937+
: ''),
938+
);
939+
});
874940
});
875941
});

packages/react-dom/src/server/ReactPartialRenderer.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,12 +889,33 @@ class ReactDOMServerRenderer {
889889
break;
890890
}
891891
}
892+
893+
let info = '';
894+
if (__DEV__) {
895+
const owner = nextElement._owner;
896+
if (
897+
elementType === undefined ||
898+
(typeof elementType === 'object' &&
899+
elementType !== null &&
900+
Object.keys(elementType).length === 0)
901+
) {
902+
info +=
903+
' You likely forgot to export your component from the file ' +
904+
"it's defined in, or you might have mixed up default and " +
905+
'named imports.';
906+
}
907+
const ownerName = owner ? getComponentName(owner) : null;
908+
if (ownerName) {
909+
info += '\n\nCheck the render method of `' + ownerName + '`.';
910+
}
911+
}
892912
invariant(
893913
false,
894914
'Element type is invalid: expected a string (for built-in ' +
895915
'components) or a class/function (for composite components) ' +
896-
'but got: %s.',
916+
'but got: %s.%s',
897917
elementType == null ? elementType : typeof elementType,
918+
info,
898919
);
899920
}
900921
}

0 commit comments

Comments
 (0)