Skip to content

Commit e068c16

Browse files
committed
Fix component name for Portal and add tests
1 parent 6db24d0 commit e068c16

File tree

2 files changed

+274
-3
lines changed

2 files changed

+274
-3
lines changed

packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js

Lines changed: 272 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
let React;
2+
let ReactDOM;
23
let ReactTestRenderer;
34
let Scheduler;
45
let Suspense;
@@ -25,6 +26,7 @@ describe('ReactLazy', () => {
2526
beforeEach(() => {
2627
jest.resetModules();
2728
React = require('react');
29+
ReactDOM = require('react-dom');
2830
Suspense = React.Suspense;
2931
lazy = React.lazy;
3032
ReactTestRenderer = require('react-test-renderer');
@@ -791,7 +793,7 @@ describe('ReactLazy', () => {
791793
);
792794
});
793795

794-
it('throws with a useful error when wrapping fragment with lazy()', async () => {
796+
it('throws with a useful error when wrapping Fragment with lazy()', async () => {
795797
const BadLazy = lazy(() => fakeImport(React.Fragment));
796798

797799
const root = ReactTestRenderer.create(
@@ -817,6 +819,275 @@ describe('ReactLazy', () => {
817819
);
818820
});
819821

822+
it('throws with a useful error when wrapping createPortal with lazy()', async () => {
823+
const container = document.createElement('div');
824+
const portal = ReactDOM.createPortal(<div />, container);
825+
const BadLazy = lazy(() => fakeImport(portal));
826+
827+
const root = ReactTestRenderer.create(
828+
<Suspense fallback={<Text text="Loading..." />}>
829+
<BadLazy />
830+
</Suspense>,
831+
{
832+
unstable_isConcurrent: true,
833+
},
834+
);
835+
836+
await waitForAll(['Loading...']);
837+
838+
await resolveFakeImport(portal);
839+
root.update(
840+
<Suspense fallback={<Text text="Loading..." />}>
841+
<BadLazy />
842+
</Suspense>,
843+
);
844+
await waitForThrow(
845+
'Element type is invalid. Received a promise that resolves to: Portal. ' +
846+
'Lazy element type must resolve to a class or function.',
847+
);
848+
});
849+
850+
it('throws with a useful error when wrapping Profiler with lazy()', async () => {
851+
const BadLazy = lazy(() => fakeImport(React.Profiler));
852+
853+
const root = ReactTestRenderer.create(
854+
<Suspense fallback={<Text text="Loading..." />}>
855+
<BadLazy />
856+
</Suspense>,
857+
{
858+
unstable_isConcurrent: true,
859+
},
860+
);
861+
862+
await waitForAll(['Loading...']);
863+
864+
await resolveFakeImport(React.Profiler);
865+
root.update(
866+
<Suspense fallback={<Text text="Loading..." />}>
867+
<BadLazy />
868+
</Suspense>,
869+
);
870+
await waitForThrow(
871+
'Element type is invalid. Received a promise that resolves to: Profiler. ' +
872+
'Lazy element type must resolve to a class or function.',
873+
);
874+
});
875+
876+
it('throws with a useful error when wrapping StrictMode with lazy()', async () => {
877+
const BadLazy = lazy(() => fakeImport(React.StrictMode));
878+
879+
const root = ReactTestRenderer.create(
880+
<Suspense fallback={<Text text="Loading..." />}>
881+
<BadLazy />
882+
</Suspense>,
883+
{
884+
unstable_isConcurrent: true,
885+
},
886+
);
887+
888+
await waitForAll(['Loading...']);
889+
890+
await resolveFakeImport(React.StrictMode);
891+
root.update(
892+
<Suspense fallback={<Text text="Loading..." />}>
893+
<BadLazy />
894+
</Suspense>,
895+
);
896+
await waitForThrow(
897+
'Element type is invalid. Received a promise that resolves to: StrictMode. ' +
898+
'Lazy element type must resolve to a class or function.',
899+
);
900+
});
901+
902+
it('throws with a useful error when wrapping Suspense with lazy()', async () => {
903+
const BadLazy = lazy(() => fakeImport(React.Suspense));
904+
905+
const root = ReactTestRenderer.create(
906+
<Suspense fallback={<Text text="Loading..." />}>
907+
<BadLazy />
908+
</Suspense>,
909+
{
910+
unstable_isConcurrent: true,
911+
},
912+
);
913+
914+
await waitForAll(['Loading...']);
915+
916+
await resolveFakeImport(React.Suspense);
917+
root.update(
918+
<Suspense fallback={<Text text="Loading..." />}>
919+
<BadLazy />
920+
</Suspense>,
921+
);
922+
await waitForThrow(
923+
'Element type is invalid. Received a promise that resolves to: Suspense. ' +
924+
'Lazy element type must resolve to a class or function.',
925+
);
926+
});
927+
928+
it('throws with a useful error when wrapping Context with lazy()', async () => {
929+
const Context = React.createContext(null);
930+
const BadLazy = lazy(() => fakeImport(Context));
931+
932+
const root = ReactTestRenderer.create(
933+
<Suspense fallback={<Text text="Loading..." />}>
934+
<BadLazy />
935+
</Suspense>,
936+
{
937+
unstable_isConcurrent: true,
938+
},
939+
);
940+
941+
await waitForAll(['Loading...']);
942+
943+
await resolveFakeImport(Context);
944+
root.update(
945+
<Suspense fallback={<Text text="Loading..." />}>
946+
<BadLazy />
947+
</Suspense>,
948+
);
949+
await waitForThrow(
950+
'Element type is invalid. Received a promise that resolves to: Context.Provider. ' +
951+
'Lazy element type must resolve to a class or function.',
952+
);
953+
});
954+
955+
// @gate enableRenderableContext
956+
it('throws with a useful error when wrapping Context.Consumer with lazy()', async () => {
957+
const Context = React.createContext(null);
958+
const BadLazy = lazy(() => fakeImport(Context.Consumer));
959+
960+
const root = ReactTestRenderer.create(
961+
<Suspense fallback={<Text text="Loading..." />}>
962+
<BadLazy />
963+
</Suspense>,
964+
{
965+
unstable_isConcurrent: true,
966+
},
967+
);
968+
969+
await waitForAll(['Loading...']);
970+
971+
await resolveFakeImport(Context.Consumer);
972+
root.update(
973+
<Suspense fallback={<Text text="Loading..." />}>
974+
<BadLazy />
975+
</Suspense>,
976+
);
977+
await waitForThrow(
978+
'Element type is invalid. Received a promise that resolves to: Context.Consumer. ' +
979+
'Lazy element type must resolve to a class or function.',
980+
);
981+
});
982+
983+
// @gate enableSuspenseList
984+
it('throws with a useful error when wrapping SuspenseList with lazy()', async () => {
985+
const BadLazy = lazy(() => fakeImport(React.unstable_SuspenseList));
986+
987+
const root = ReactTestRenderer.create(
988+
<Suspense fallback={<Text text="Loading..." />}>
989+
<BadLazy />
990+
</Suspense>,
991+
{
992+
unstable_isConcurrent: true,
993+
},
994+
);
995+
996+
await waitForAll(['Loading...']);
997+
998+
await resolveFakeImport(React.unstable_SuspenseList);
999+
root.update(
1000+
<Suspense fallback={<Text text="Loading..." />}>
1001+
<BadLazy />
1002+
</Suspense>,
1003+
);
1004+
await waitForThrow(
1005+
'Element type is invalid. Received a promise that resolves to: SuspenseList. ' +
1006+
'Lazy element type must resolve to a class or function.',
1007+
);
1008+
});
1009+
1010+
// @gate enableViewTransition
1011+
it('throws with a useful error when wrapping ViewTransition with lazy()', async () => {
1012+
const BadLazy = lazy(() => fakeImport(React.unstable_ViewTransition));
1013+
1014+
const root = ReactTestRenderer.create(
1015+
<Suspense fallback={<Text text="Loading..." />}>
1016+
<BadLazy />
1017+
</Suspense>,
1018+
{
1019+
unstable_isConcurrent: true,
1020+
},
1021+
);
1022+
1023+
await waitForAll(['Loading...']);
1024+
1025+
await resolveFakeImport(React.unstable_ViewTransition);
1026+
root.update(
1027+
<Suspense fallback={<Text text="Loading..." />}>
1028+
<BadLazy />
1029+
</Suspense>,
1030+
);
1031+
await waitForThrow(
1032+
'Element type is invalid. Received a promise that resolves to: ViewTransition. ' +
1033+
'Lazy element type must resolve to a class or function.',
1034+
);
1035+
});
1036+
1037+
// @gate enableActivity
1038+
it('throws with a useful error when wrapping Activity with lazy()', async () => {
1039+
const BadLazy = lazy(() => fakeImport(React.unstable_Activity));
1040+
1041+
const root = ReactTestRenderer.create(
1042+
<Suspense fallback={<Text text="Loading..." />}>
1043+
<BadLazy />
1044+
</Suspense>,
1045+
{
1046+
unstable_isConcurrent: true,
1047+
},
1048+
);
1049+
1050+
await waitForAll(['Loading...']);
1051+
1052+
await resolveFakeImport(React.unstable_Activity);
1053+
root.update(
1054+
<Suspense fallback={<Text text="Loading..." />}>
1055+
<BadLazy />
1056+
</Suspense>,
1057+
);
1058+
await waitForThrow(
1059+
'Element type is invalid. Received a promise that resolves to: Activity. ' +
1060+
'Lazy element type must resolve to a class or function.',
1061+
);
1062+
});
1063+
1064+
// @gate enableTransitionTracing
1065+
it('throws with a useful error when wrapping TracingMarker with lazy()', async () => {
1066+
const BadLazy = lazy(() => fakeImport(React.unstable_TracingMarker));
1067+
1068+
const root = ReactTestRenderer.create(
1069+
<Suspense fallback={<Text text="Loading..." />}>
1070+
<BadLazy />
1071+
</Suspense>,
1072+
{
1073+
unstable_isConcurrent: true,
1074+
},
1075+
);
1076+
1077+
await waitForAll(['Loading...']);
1078+
1079+
await resolveFakeImport(React.unstable_TracingMarker);
1080+
root.update(
1081+
<Suspense fallback={<Text text="Loading..." />}>
1082+
<BadLazy />
1083+
</Suspense>,
1084+
);
1085+
await waitForThrow(
1086+
'Element type is invalid. Received a promise that resolves to: TracingMarker. ' +
1087+
'Lazy element type must resolve to a class or function.',
1088+
);
1089+
});
1090+
8201091
it('throws with a useful error when wrapping lazy() multiple times', async () => {
8211092
const Lazy1 = lazy(() => fakeImport(Text));
8221093
const Lazy2 = lazy(() => fakeImport(Lazy1));

packages/shared/getComponentNameFromType.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ export default function getComponentNameFromType(type: mixed): string | null {
7474
switch (type) {
7575
case REACT_FRAGMENT_TYPE:
7676
return 'Fragment';
77-
case REACT_PORTAL_TYPE:
78-
return 'Portal';
7977
case REACT_PROFILER_TYPE:
8078
return 'Profiler';
8179
case REACT_STRICT_MODE_TYPE:
@@ -106,6 +104,8 @@ export default function getComponentNameFromType(type: mixed): string | null {
106104
}
107105
}
108106
switch (type.$$typeof) {
107+
case REACT_PORTAL_TYPE:
108+
return 'Portal';
109109
case REACT_PROVIDER_TYPE:
110110
if (enableRenderableContext) {
111111
return null;

0 commit comments

Comments
 (0)