Skip to content

Commit efebb67

Browse files
committed
Change API to overrideSuspense
This lets detect support for overriding Suspense from DevTools.
1 parent d26d182 commit efebb67

File tree

4 files changed

+49
-41
lines changed

4 files changed

+49
-41
lines changed

packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,18 @@ describe('React hooks DevTools integration', () => {
1717
let act;
1818
let overrideHookState;
1919
let overrideProps;
20-
let suspendedFibers;
20+
let overrideSuspense;
2121

2222
beforeEach(() => {
23-
suspendedFibers = new Set();
2423
global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
2524
inject: injected => {
2625
overrideHookState = injected.overrideHookState;
2726
overrideProps = injected.overrideProps;
27+
overrideSuspense = injected.overrideSuspense;
2828
},
2929
supportsFiber: true,
3030
onCommitFiberRoot: () => {},
3131
onCommitFiberUnmount: () => {},
32-
shouldSuspendFiber(rendererId, fiber) {
33-
return (
34-
suspendedFibers.has(fiber) ||
35-
(fiber.alternate && suspendedFibers.has(fiber.alternate))
36-
);
37-
},
3832
};
3933

4034
jest.resetModules();
@@ -184,40 +178,56 @@ describe('React hooks DevTools integration', () => {
184178
}
185179
});
186180

187-
it('should support triggering suspense in DEV', () => {
181+
it('should support overriding suspense', () => {
182+
if (__DEV__) {
183+
// Lock the first render
184+
overrideSuspense(() => true);
185+
}
186+
188187
function MyComponent() {
189188
return 'Done';
190189
}
191190

192191
const renderer = ReactTestRenderer.create(
193-
<React.Suspense fallback={'Loading'}>
194-
<MyComponent />
195-
</React.Suspense>,
192+
<div>
193+
<React.Suspense fallback={'Loading'}>
194+
<MyComponent />
195+
</React.Suspense>
196+
</div>,
196197
);
197-
expect(renderer.toJSON()).toEqual('Done');
198-
199-
const fiber = renderer.root._currentFiber().return;
198+
const fiber = renderer.root._currentFiber().child;
200199
if (__DEV__) {
201-
// Mark as loading
202-
suspendedFibers.add(fiber);
200+
// First render was locked
201+
expect(renderer.toJSON().children).toEqual(['Loading']);
203202
overrideProps(fiber, [], null); // Re-render
204-
expect(renderer.toJSON()).toEqual('Loading');
203+
expect(renderer.toJSON().children).toEqual(['Loading']);
204+
// Release the lock
205+
overrideSuspense(() => false);
205206

206207
overrideProps(fiber, [], null); // Re-render
207-
expect(renderer.toJSON()).toEqual('Loading');
208+
expect(renderer.toJSON().children).toEqual(['Done']);
209+
overrideProps(fiber, [], null); // Re-render
210+
expect(renderer.toJSON().children).toEqual(['Done']);
208211

209-
// Mark as done
210-
suspendedFibers.delete(fiber);
212+
// Lock again
213+
overrideSuspense(() => true);
211214
overrideProps(fiber, [], null); // Re-render
212-
expect(renderer.toJSON()).toEqual('Done');
215+
expect(renderer.toJSON().children).toEqual(['Loading']);
213216

217+
// Release the lock again
218+
overrideSuspense(() => false);
214219
overrideProps(fiber, [], null); // Re-render
215-
expect(renderer.toJSON()).toEqual('Done');
220+
expect(renderer.toJSON().children).toEqual(['Done']);
216221

217-
// Mark as loading again
218-
suspendedFibers.add(fiber);
222+
// Ensure it checks specific fibers.
223+
overrideSuspense(f => f === fiber || f === fiber.alternate);
224+
overrideProps(fiber, [], null); // Re-render
225+
expect(renderer.toJSON().children).toEqual(['Loading']);
226+
overrideSuspense(f => f !== fiber && f !== fiber.alternate);
219227
overrideProps(fiber, [], null); // Re-render
220-
expect(renderer.toJSON()).toEqual('Loading');
228+
expect(renderer.toJSON().children).toEqual(['Done']);
229+
} else {
230+
expect(renderer.toJSON().children).toEqual(['Done']);
221231
}
222232
});
223233
});

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ import {
7777
cloneChildFibers,
7878
} from './ReactChildFiber';
7979
import {processUpdateQueue} from './ReactUpdateQueue';
80-
import {shouldSuspend} from './ReactFiberDevToolsHook';
8180
import {
8281
NoWork,
8382
Never,
@@ -97,6 +96,7 @@ import {
9796
registerSuspenseInstanceRetry,
9897
} from './ReactFiberHostConfig';
9998
import type {SuspenseInstance} from './ReactFiberHostConfig';
99+
import {shouldSuspend} from './ReactFiberReconciler';
100100
import {
101101
pushHostContext,
102102
pushHostContainer,

packages/react-reconciler/src/ReactFiberDevToolsHook.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
1616

1717
let onCommitFiberRoot = null;
1818
let onCommitFiberUnmount = null;
19-
let shouldSuspendFiber = function() {
20-
return false;
21-
};
2219
let hasLoggedError = false;
2320

2421
function catchErrors(fn) {
@@ -74,13 +71,6 @@ export function injectInternals(internals: Object): boolean {
7471
onCommitFiberUnmount = catchErrors(fiber =>
7572
hook.onCommitFiberUnmount(rendererID, fiber),
7673
);
77-
if (__DEV__) {
78-
if (hook.shouldSuspendFiber) {
79-
shouldSuspendFiber = catchErrors(fiber =>
80-
hook.shouldSuspendFiber(rendererID, fiber),
81-
);
82-
}
83-
}
8474
} catch (err) {
8575
// Catch all errors because it is unsafe to throw during initialization.
8676
if (__DEV__) {
@@ -106,7 +96,3 @@ export function onCommitUnmount(fiber: Fiber) {
10696
onCommitFiberUnmount(fiber);
10797
}
10898
}
109-
110-
export function shouldSuspend(fiber: Fiber) {
111-
return shouldSuspendFiber(fiber);
112-
}

packages/react-reconciler/src/ReactFiberReconciler.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,15 @@ export function findHostInstanceWithNoPortals(
340340
return hostFiber.stateNode;
341341
}
342342

343+
let shouldSuspendImpl = fiber => false;
344+
345+
export function shouldSuspend(fiber: Fiber): boolean {
346+
return shouldSuspendImpl(fiber);
347+
}
348+
343349
let overrideHookState = null;
344350
let overrideProps = null;
351+
let overrideSuspense = null;
345352

346353
if (__DEV__) {
347354
const copyWithSetImpl = (
@@ -413,6 +420,10 @@ if (__DEV__) {
413420
}
414421
scheduleWork(fiber, Sync);
415422
};
423+
424+
overrideSuspense = (newShouldSuspendImpl: Fiber => boolean) => {
425+
shouldSuspendImpl = newShouldSuspendImpl;
426+
};
416427
}
417428

418429
export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
@@ -423,6 +434,7 @@ export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
423434
...devToolsConfig,
424435
overrideHookState,
425436
overrideProps,
437+
overrideSuspense,
426438
currentDispatcherRef: ReactCurrentDispatcher,
427439
findHostInstanceByFiber(fiber: Fiber): Instance | TextInstance | null {
428440
const hostFiber = findCurrentHostFiber(fiber);

0 commit comments

Comments
 (0)