Skip to content

Commit b7cbc29

Browse files
committed
[crud] Merge useResourceEffect into useEffect
Merges the useResourceEffect API into useEffect while keeping the underlying implementation the same. useResourceEffect will be removed in the next diff. To fork between behavior we rely on a `typeof` check for the updater or destroy function in addition to the CRUD feature flag. This does now have to be checked every time (instead of inlined statically like before due to them being different hooks) which will incur some non-zero amount (possibly negligble) of overhead for every effect.
1 parent 2c6aaf8 commit b7cbc29

File tree

9 files changed

+279
-143
lines changed

9 files changed

+279
-143
lines changed

packages/react-debug-tools/src/ReactDebugHooks.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,11 @@ function useInsertionEffect(
373373
}
374374

375375
function useEffect(
376-
create: () => (() => void) | void,
377-
inputs: Array<mixed> | void | null,
376+
create: (() => (() => void) | void) | (() => {...} | void | null),
377+
createDeps: Array<mixed> | void | null,
378+
update?: ((resource: {...} | void | null) => void) | void,
379+
updateDeps?: Array<mixed> | void | null,
380+
destroy?: ((resource: {...} | void | null) => void) | void,
378381
): void {
379382
nextHook();
380383
hookLog.push({

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ let useRef;
2727
let useImperativeHandle;
2828
let useInsertionEffect;
2929
let useLayoutEffect;
30-
let useResourceEffect;
3130
let useDebugValue;
3231
let forwardRef;
3332
let yieldedValues;
@@ -52,7 +51,6 @@ function initModules() {
5251
useImperativeHandle = React.useImperativeHandle;
5352
useInsertionEffect = React.useInsertionEffect;
5453
useLayoutEffect = React.useLayoutEffect;
55-
useResourceEffect = React.experimental_useResourceEffect;
5654
forwardRef = React.forwardRef;
5755

5856
yieldedValues = [];
@@ -655,15 +653,15 @@ describe('ReactDOMServerHooks', () => {
655653
});
656654
});
657655

658-
describe('useResourceEffect', () => {
656+
describe('useEffect with CRUD overload', () => {
659657
gate(flags => {
660658
if (flags.enableUseEffectCRUDOverload) {
661659
const yields = [];
662660
itRenders(
663661
'should ignore resource effects on the server',
664662
async render => {
665663
function Counter(props) {
666-
useResourceEffect(
664+
useEffect(
667665
() => {
668666
yieldValue('created on client');
669667
return {resource_counter: props.count};

packages/react-reconciler/src/ReactFiberCallUserSpace.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ const callDestroy = {
254254
export const callDestroyInDEV: (
255255
current: Fiber,
256256
nearestMountedAncestor: Fiber | null,
257-
destroy: () => void,
257+
destroy: (() => void) | (({...}) => void),
258258
) => void = __DEV__
259259
? // We use this technique to trick minifiers to preserve the function name.
260260
(callDestroy['react-stack-bottom-frame'].bind(callDestroy): any)

packages/react-reconciler/src/ReactFiberCommitEffects.js

+8-33
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ export function commitHookEffectListMount(
170170
);
171171
if (effect.inst.resource == null) {
172172
console.error(
173-
'useResourceEffect must provide a callback which returns a resource. ' +
174-
'If a managed resource is not needed here, use useEffect. Received %s',
173+
'useEffect must provide a callback which returns a resource. ' +
174+
'If a managed resource is not needed here, do not provide an updater or ' +
175+
'destroy callback. Received %s',
175176
effect.inst.resource,
176177
);
177178
}
@@ -261,11 +262,6 @@ export function commitHookEffectListMount(
261262
hookName = 'useLayoutEffect';
262263
} else if ((effect.tag & HookInsertion) !== NoFlags) {
263264
hookName = 'useInsertionEffect';
264-
} else if (
265-
enableUseEffectCRUDOverload &&
266-
effect.resourceKind != null
267-
) {
268-
hookName = 'useResourceEffect';
269265
} else {
270266
hookName = 'useEffect';
271267
}
@@ -363,7 +359,7 @@ export function commitHookEffectListUnmount(
363359
effect.resourceKind === ResourceEffectIdentityKind &&
364360
effect.inst.resource != null
365361
) {
366-
safelyCallDestroyWithResource(
362+
safelyCallDestroy(
367363
finishedWork,
368364
nearestMountedAncestor,
369365
destroy,
@@ -1015,32 +1011,11 @@ export function safelyDetachRef(
10151011
function safelyCallDestroy(
10161012
current: Fiber,
10171013
nearestMountedAncestor: Fiber | null,
1018-
destroy: () => void,
1019-
) {
1020-
if (__DEV__) {
1021-
runWithFiberInDEV(
1022-
current,
1023-
callDestroyInDEV,
1024-
current,
1025-
nearestMountedAncestor,
1026-
destroy,
1027-
);
1028-
} else {
1029-
try {
1030-
destroy();
1031-
} catch (error) {
1032-
captureCommitPhaseError(current, nearestMountedAncestor, error);
1033-
}
1034-
}
1035-
}
1036-
1037-
function safelyCallDestroyWithResource(
1038-
current: Fiber,
1039-
nearestMountedAncestor: Fiber | null,
1040-
destroy: ({...}) => void,
1041-
resource: {...},
1014+
destroy: (() => void) | (({...}) => void),
1015+
resource?: {...} | void | null,
10421016
) {
1043-
const destroy_ = destroy.bind(null, resource);
1017+
// $FlowFixMe[extra-arg] @poteto this is safe either way because the extra arg is ignored if it's not a CRUD effect
1018+
const destroy_ = resource == null ? destroy : destroy.bind(null, resource);
10441019
if (__DEV__) {
10451020
runWithFiberInDEV(
10461021
current,

0 commit comments

Comments
 (0)