Error gracefully for unsupported SSR features (#13839)
Dan Abramov committed
Oct 12, 2018 at 14:47 UTC
8ca8a594e6fc7dfcba73b8595344e7522d40171d
3 files changed
+74
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+23
@@ -566,6 +566,29 @@ describe('ReactDOMServer', () => {
566
expect(markup).toBe('<div></div>');
567
});
568
569
+ it('throws for unsupported types on the server', () => {
570
+ expect(() => {
571
+ ReactDOMServer.renderToString(<React.unstable_Suspense />);
572
+ }).toThrow('ReactDOMServer does not yet support Suspense.');
573
+
574
+ expect(() => {
575
+ const LazyFoo = React.lazy(
576
+ () =>
577
+ new Promise(resolve =>
578
+ resolve(function Foo() {
579
+ return <div />;
580
+ }),
581
+ ),
582
+ );
583
+ ReactDOMServer.renderToString(<LazyFoo />);
584
+ }).toThrow('ReactDOMServer does not yet support lazy-loaded components.');
585
+
586
+ expect(() => {
587
+ const FooPromise = {then() {}};
588
+ ReactDOMServer.renderToString(<FooPromise />);
589
+ }).toThrow('ReactDOMServer does not yet support lazy-loaded components.');
590
+ });
591
+
592
it('should throw (in dev) when children are mutated during render', () => {
593
function Wrapper(props) {
594
props.children[1] = <p key={1} />; // Mutation is illegal
packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+43
@@ -442,4 +442,47 @@ describe('ReactDOMServerHydration', () => {
442
'<div>Enable JavaScript to run this app.</div>',
443
);
444
});
445
+
446
+ it('should be able to use lazy components after hydrating', async () => {
447
+ const Lazy = new Promise(resolve => {
448
+ setTimeout(
449
+ () =>
450
+ resolve(function World() {
451
+ return 'world';
452
+ }),
453
+ 1000,
454
+ );
455
+ });
456
+ class HelloWorld extends React.Component {
457
+ state = {isClient: false};
458
+ componentDidMount() {
459
+ this.setState({
460
+ isClient: true,
461
+ });
462
+ }
463
+ render() {
464
+ return (
465
+ <div>
466
+ Hello{' '}
467
+ {this.state.isClient && (
468
+ <React.unstable_Suspense fallback="loading">
469
+ <Lazy />
470
+ </React.unstable_Suspense>
471
+ )}
472
+ </div>
473
+ );
474
+ }
475
+ }
476
+
477
+ const element = document.createElement('div');
478
+ element.innerHTML = ReactDOMServer.renderToString(<HelloWorld />);
479
+ expect(element.textContent).toBe('Hello ');
480
+
481
+ ReactDOM.hydrate(<HelloWorld />, element);
482
+ expect(element.textContent).toBe('Hello loading');
483
+
484
+ jest.runAllTimers();
485
+ await Lazy;
486
+ expect(element.textContent).toBe('Hello world');
487
+ });
488
});
packages/react-dom/src/server/ReactPartialRenderer.js
+8
@@ -935,6 +935,8 @@ class ReactDOMServerRenderer {
935
}
936
this.stack.push(frame);
937
return '';
938
+ } else {
939
+ invariant(false, 'ReactDOMServer does not yet support Suspense.');
940
}
941
}
942
// eslint-disable-next-line-no-fallthrough
@@ -1004,6 +1006,12 @@ class ReactDOMServerRenderer {
1006
return '';
1007
}
1008
default:
1009
+ if (typeof elementType.then === 'function') {
1010
+ invariant(
1011
+ false,
1012
+ 'ReactDOMServer does not yet support lazy-loaded components.',
1013
+ );
1014
+ }
1015
break;
1016
}
1017
}