diff --git a/packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js
index 2b8087274dde..0d8e32ba06c7 100644
--- a/packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js
+++ b/packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js
@@ -17,24 +17,18 @@ describe('React hooks DevTools integration', () => {
let act;
let overrideHookState;
let overrideProps;
- let suspendedFibers;
+ let overrideSuspense;
beforeEach(() => {
- suspendedFibers = new Set();
global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
inject: injected => {
overrideHookState = injected.overrideHookState;
overrideProps = injected.overrideProps;
+ overrideSuspense = injected.overrideSuspense;
},
supportsFiber: true,
onCommitFiberRoot: () => {},
onCommitFiberUnmount: () => {},
- shouldSuspendFiber(rendererId, fiber) {
- return (
- suspendedFibers.has(fiber) ||
- (fiber.alternate && suspendedFibers.has(fiber.alternate))
- );
- },
};
jest.resetModules();
@@ -184,40 +178,56 @@ describe('React hooks DevTools integration', () => {
}
});
- it('should support triggering suspense in DEV', () => {
+ it('should support overriding suspense', () => {
+ if (__DEV__) {
+ // Lock the first render
+ overrideSuspense(() => true);
+ }
+
function MyComponent() {
return 'Done';
}
const renderer = ReactTestRenderer.create(
-
-
- ,
+
+
+
+
+
,
);
- expect(renderer.toJSON()).toEqual('Done');
-
- const fiber = renderer.root._currentFiber().return;
+ const fiber = renderer.root._currentFiber().child;
if (__DEV__) {
- // Mark as loading
- suspendedFibers.add(fiber);
+ // First render was locked
+ expect(renderer.toJSON().children).toEqual(['Loading']);
overrideProps(fiber, [], null); // Re-render
- expect(renderer.toJSON()).toEqual('Loading');
+ expect(renderer.toJSON().children).toEqual(['Loading']);
+ // Release the lock
+ overrideSuspense(() => false);
overrideProps(fiber, [], null); // Re-render
- expect(renderer.toJSON()).toEqual('Loading');
+ expect(renderer.toJSON().children).toEqual(['Done']);
+ overrideProps(fiber, [], null); // Re-render
+ expect(renderer.toJSON().children).toEqual(['Done']);
- // Mark as done
- suspendedFibers.delete(fiber);
+ // Lock again
+ overrideSuspense(() => true);
overrideProps(fiber, [], null); // Re-render
- expect(renderer.toJSON()).toEqual('Done');
+ expect(renderer.toJSON().children).toEqual(['Loading']);
+ // Release the lock again
+ overrideSuspense(() => false);
overrideProps(fiber, [], null); // Re-render
- expect(renderer.toJSON()).toEqual('Done');
+ expect(renderer.toJSON().children).toEqual(['Done']);
- // Mark as loading again
- suspendedFibers.add(fiber);
+ // Ensure it checks specific fibers.
+ overrideSuspense(f => f === fiber || f === fiber.alternate);
+ overrideProps(fiber, [], null); // Re-render
+ expect(renderer.toJSON().children).toEqual(['Loading']);
+ overrideSuspense(f => f !== fiber && f !== fiber.alternate);
overrideProps(fiber, [], null); // Re-render
- expect(renderer.toJSON()).toEqual('Loading');
+ expect(renderer.toJSON().children).toEqual(['Done']);
+ } else {
+ expect(renderer.toJSON().children).toEqual(['Done']);
}
});
});
diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js
index 01b60efffe3a..2832021950f6 100644
--- a/packages/react-reconciler/src/ReactFiberBeginWork.js
+++ b/packages/react-reconciler/src/ReactFiberBeginWork.js
@@ -77,7 +77,6 @@ import {
cloneChildFibers,
} from './ReactChildFiber';
import {processUpdateQueue} from './ReactUpdateQueue';
-import {shouldSuspend} from './ReactFiberDevToolsHook';
import {
NoWork,
Never,
@@ -97,6 +96,7 @@ import {
registerSuspenseInstanceRetry,
} from './ReactFiberHostConfig';
import type {SuspenseInstance} from './ReactFiberHostConfig';
+import {shouldSuspend} from './ReactFiberReconciler';
import {
pushHostContext,
pushHostContainer,
diff --git a/packages/react-reconciler/src/ReactFiberDevToolsHook.js b/packages/react-reconciler/src/ReactFiberDevToolsHook.js
index ba8432cb269b..f7bebce841d5 100644
--- a/packages/react-reconciler/src/ReactFiberDevToolsHook.js
+++ b/packages/react-reconciler/src/ReactFiberDevToolsHook.js
@@ -16,9 +16,6 @@ declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
let onCommitFiberRoot = null;
let onCommitFiberUnmount = null;
-let shouldSuspendFiber = function() {
- return false;
-};
let hasLoggedError = false;
function catchErrors(fn) {
@@ -74,13 +71,6 @@ export function injectInternals(internals: Object): boolean {
onCommitFiberUnmount = catchErrors(fiber =>
hook.onCommitFiberUnmount(rendererID, fiber),
);
- if (__DEV__) {
- if (hook.shouldSuspendFiber) {
- shouldSuspendFiber = catchErrors(fiber =>
- hook.shouldSuspendFiber(rendererID, fiber),
- );
- }
- }
} catch (err) {
// Catch all errors because it is unsafe to throw during initialization.
if (__DEV__) {
@@ -106,7 +96,3 @@ export function onCommitUnmount(fiber: Fiber) {
onCommitFiberUnmount(fiber);
}
}
-
-export function shouldSuspend(fiber: Fiber) {
- return shouldSuspendFiber(fiber);
-}
diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js
index a01df581faa5..b985392e81c0 100644
--- a/packages/react-reconciler/src/ReactFiberReconciler.js
+++ b/packages/react-reconciler/src/ReactFiberReconciler.js
@@ -340,8 +340,15 @@ export function findHostInstanceWithNoPortals(
return hostFiber.stateNode;
}
+let shouldSuspendImpl = fiber => false;
+
+export function shouldSuspend(fiber: Fiber): boolean {
+ return shouldSuspendImpl(fiber);
+}
+
let overrideHookState = null;
let overrideProps = null;
+let overrideSuspense = null;
if (__DEV__) {
const copyWithSetImpl = (
@@ -413,6 +420,10 @@ if (__DEV__) {
}
scheduleWork(fiber, Sync);
};
+
+ overrideSuspense = (newShouldSuspendImpl: Fiber => boolean) => {
+ shouldSuspendImpl = newShouldSuspendImpl;
+ };
}
export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
@@ -423,6 +434,7 @@ export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
...devToolsConfig,
overrideHookState,
overrideProps,
+ overrideSuspense,
currentDispatcherRef: ReactCurrentDispatcher,
findHostInstanceByFiber(fiber: Fiber): Instance | TextInstance | null {
const hostFiber = findCurrentHostFiber(fiber);