Skip to content

Commit 8cd8417

Browse files
gaearonjetoneza
authored andcommitted
Error gracefully for unsupported SSR features (facebook#13839)
1 parent 8458131 commit 8cd8417

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,29 @@ describe('ReactDOMServer', () => {
566566
expect(markup).toBe('<div></div>');
567567
});
568568

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+
569592
it('should throw (in dev) when children are mutated during render', () => {
570593
function Wrapper(props) {
571594
props.children[1] = <p key={1} />; // Mutation is illegal

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,4 +442,47 @@ describe('ReactDOMServerHydration', () => {
442442
'<div>Enable JavaScript to run this app.</div>',
443443
);
444444
});
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+
});
445488
});

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,8 @@ class ReactDOMServerRenderer {
935935
}
936936
this.stack.push(frame);
937937
return '';
938+
} else {
939+
invariant(false, 'ReactDOMServer does not yet support Suspense.');
938940
}
939941
}
940942
// eslint-disable-next-line-no-fallthrough
@@ -1004,6 +1006,12 @@ class ReactDOMServerRenderer {
10041006
return '';
10051007
}
10061008
default:
1009+
if (typeof elementType.then === 'function') {
1010+
invariant(
1011+
false,
1012+
'ReactDOMServer does not yet support lazy-loaded components.',
1013+
);
1014+
}
10071015
break;
10081016
}
10091017
}

0 commit comments

Comments
 (0)