Skip to content

Commit dedfeff

Browse files
committed
Revert "experimental_use(promise) for SSR (facebook#25214)"
This reverts commit c28f313. Follow up to facebook#25084 and facebook#25207. Implements experimental_use(promise) API in the SSR runtime (Fizz). This is largely a copy-paste of the Flight implementation. I have intentionally tried to keep both as close as possible.
1 parent 0dfb986 commit dedfeff

File tree

4 files changed

+30
-415
lines changed

4 files changed

+30
-415
lines changed

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

-212
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ let Suspense;
2525
let SuspenseList;
2626
let useSyncExternalStore;
2727
let useSyncExternalStoreWithSelector;
28-
let use;
2928
let PropTypes;
3029
let textCache;
3130
let window;
@@ -48,7 +47,6 @@ describe('ReactDOMFizzServer', () => {
4847
ReactDOMFizzServer = require('react-dom/server');
4948
Stream = require('stream');
5049
Suspense = React.Suspense;
51-
use = React.use;
5250
if (gate(flags => flags.enableSuspenseList)) {
5351
SuspenseList = React.SuspenseList;
5452
}
@@ -5168,216 +5166,6 @@ describe('ReactDOMFizzServer', () => {
51685166
console.error = originalConsoleError;
51695167
}
51705168
});
5171-
5172-
// @gate enableUseHook
5173-
it('basic use(promise)', async () => {
5174-
const promiseA = Promise.resolve('A');
5175-
const promiseB = Promise.resolve('B');
5176-
const promiseC = Promise.resolve('C');
5177-
5178-
function Async() {
5179-
return use(promiseA) + use(promiseB) + use(promiseC);
5180-
}
5181-
5182-
function App() {
5183-
return (
5184-
<Suspense fallback="Loading...">
5185-
<Async />
5186-
</Suspense>
5187-
);
5188-
}
5189-
5190-
await act(async () => {
5191-
const {pipe} = renderToPipeableStream(<App />);
5192-
pipe(writable);
5193-
});
5194-
5195-
// TODO: The `act` implementation in this file doesn't unwrap microtasks
5196-
// automatically. We can't use the same `act` we use for Fiber tests
5197-
// because that relies on the mock Scheduler. Doesn't affect any public
5198-
// API but we might want to fix this for our own internal tests.
5199-
//
5200-
// For now, wait for each promise in sequence.
5201-
await act(async () => {
5202-
await promiseA;
5203-
});
5204-
await act(async () => {
5205-
await promiseB;
5206-
});
5207-
await act(async () => {
5208-
await promiseC;
5209-
});
5210-
5211-
expect(getVisibleChildren(container)).toEqual('ABC');
5212-
5213-
ReactDOMClient.hydrateRoot(container, <App />);
5214-
expect(Scheduler).toFlushAndYield([]);
5215-
expect(getVisibleChildren(container)).toEqual('ABC');
5216-
});
5217-
5218-
// @gate enableUseHook
5219-
it('use(promise) in multiple components', async () => {
5220-
const promiseA = Promise.resolve('A');
5221-
const promiseB = Promise.resolve('B');
5222-
const promiseC = Promise.resolve('C');
5223-
const promiseD = Promise.resolve('D');
5224-
5225-
function Child({prefix}) {
5226-
return prefix + use(promiseC) + use(promiseD);
5227-
}
5228-
5229-
function Parent() {
5230-
return <Child prefix={use(promiseA) + use(promiseB)} />;
5231-
}
5232-
5233-
function App() {
5234-
return (
5235-
<Suspense fallback="Loading...">
5236-
<Parent />
5237-
</Suspense>
5238-
);
5239-
}
5240-
5241-
await act(async () => {
5242-
const {pipe} = renderToPipeableStream(<App />);
5243-
pipe(writable);
5244-
});
5245-
5246-
// TODO: The `act` implementation in this file doesn't unwrap microtasks
5247-
// automatically. We can't use the same `act` we use for Fiber tests
5248-
// because that relies on the mock Scheduler. Doesn't affect any public
5249-
// API but we might want to fix this for our own internal tests.
5250-
//
5251-
// For now, wait for each promise in sequence.
5252-
await act(async () => {
5253-
await promiseA;
5254-
});
5255-
await act(async () => {
5256-
await promiseB;
5257-
});
5258-
await act(async () => {
5259-
await promiseC;
5260-
});
5261-
await act(async () => {
5262-
await promiseD;
5263-
});
5264-
5265-
expect(getVisibleChildren(container)).toEqual('ABCD');
5266-
5267-
ReactDOMClient.hydrateRoot(container, <App />);
5268-
expect(Scheduler).toFlushAndYield([]);
5269-
expect(getVisibleChildren(container)).toEqual('ABCD');
5270-
});
5271-
5272-
// @gate enableUseHook
5273-
it('using a rejected promise will throw', async () => {
5274-
const promiseA = Promise.resolve('A');
5275-
const promiseB = Promise.reject(new Error('Oops!'));
5276-
const promiseC = Promise.resolve('C');
5277-
5278-
// Jest/Node will raise an unhandled rejected error unless we await this. It
5279-
// works fine in the browser, though.
5280-
await expect(promiseB).rejects.toThrow('Oops!');
5281-
5282-
function Async() {
5283-
return use(promiseA) + use(promiseB) + use(promiseC);
5284-
}
5285-
5286-
class ErrorBoundary extends React.Component {
5287-
state = {error: null};
5288-
static getDerivedStateFromError(error) {
5289-
return {error};
5290-
}
5291-
render() {
5292-
if (this.state.error) {
5293-
return this.state.error.message;
5294-
}
5295-
return this.props.children;
5296-
}
5297-
}
5298-
5299-
function App() {
5300-
return (
5301-
<Suspense fallback="Loading...">
5302-
<ErrorBoundary>
5303-
<Async />
5304-
</ErrorBoundary>
5305-
</Suspense>
5306-
);
5307-
}
5308-
5309-
const reportedServerErrors = [];
5310-
await act(async () => {
5311-
const {pipe} = renderToPipeableStream(<App />, {
5312-
onError(error) {
5313-
reportedServerErrors.push(error);
5314-
},
5315-
});
5316-
pipe(writable);
5317-
});
5318-
5319-
// TODO: The `act` implementation in this file doesn't unwrap microtasks
5320-
// automatically. We can't use the same `act` we use for Fiber tests
5321-
// because that relies on the mock Scheduler. Doesn't affect any public
5322-
// API but we might want to fix this for our own internal tests.
5323-
//
5324-
// For now, wait for each promise in sequence.
5325-
await act(async () => {
5326-
await promiseA;
5327-
});
5328-
await act(async () => {
5329-
await expect(promiseB).rejects.toThrow('Oops!');
5330-
});
5331-
await act(async () => {
5332-
await promiseC;
5333-
});
5334-
5335-
expect(getVisibleChildren(container)).toEqual('Loading...');
5336-
expect(reportedServerErrors.length).toBe(1);
5337-
expect(reportedServerErrors[0].message).toBe('Oops!');
5338-
5339-
const reportedClientErrors = [];
5340-
ReactDOMClient.hydrateRoot(container, <App />, {
5341-
onRecoverableError(error) {
5342-
reportedClientErrors.push(error);
5343-
},
5344-
});
5345-
expect(Scheduler).toFlushAndYield([]);
5346-
expect(getVisibleChildren(container)).toEqual('Oops!');
5347-
expect(reportedClientErrors.length).toBe(1);
5348-
if (__DEV__) {
5349-
expect(reportedClientErrors[0].message).toBe('Oops!');
5350-
} else {
5351-
expect(reportedClientErrors[0].message).toBe(
5352-
'The server could not finish this Suspense boundary, likely due to ' +
5353-
'an error during server rendering. Switched to client rendering.',
5354-
);
5355-
}
5356-
});
5357-
5358-
// @gate enableUseHook
5359-
it("use a promise that's already been instrumented and resolved", async () => {
5360-
const thenable = {
5361-
status: 'fulfilled',
5362-
value: 'Hi',
5363-
then() {},
5364-
};
5365-
5366-
// This will never suspend because the thenable already resolved
5367-
function App() {
5368-
return use(thenable);
5369-
}
5370-
5371-
await act(async () => {
5372-
const {pipe} = renderToPipeableStream(<App />);
5373-
pipe(writable);
5374-
});
5375-
expect(getVisibleChildren(container)).toEqual('Hi');
5376-
5377-
ReactDOMClient.hydrateRoot(container, <App />);
5378-
expect(Scheduler).toFlushAndYield([]);
5379-
expect(getVisibleChildren(container)).toEqual('Hi');
5380-
});
53815169
});
53825170

53835171
describe('useEvent', () => {

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js

+1
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ describe('ReactFlightDOMBrowser', () => {
462462
});
463463

464464
// @gate enableUseHook
465+
// @gate FIXME // Depends on `use` (which was temporarily reverted in Fizz)
465466
it('should allow an alternative module mapping to be used for SSR', async () => {
466467
function ClientComponent() {
467468
return <span>Client Component</span>;

0 commit comments

Comments
 (0)