Skip to content

Commit 708c60a

Browse files
committed
Remove useMutationEffect
useMutationEffect has problems (namely, refs aren't attached at the time that it runs) and we're not positive it's necessary. useLayoutEffect runs at the same time as componentDidMount/Update so it's sufficient for all existing use cases; it can be used in any case that useEffect happens too late. Until we figure out what we want to do, let's delete it.
1 parent 48f1e5b commit 708c60a

File tree

11 files changed

+22
-275
lines changed

11 files changed

+22
-275
lines changed

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
5252
Dispatcher.useState(null);
5353
Dispatcher.useReducer((s, a) => s, null);
5454
Dispatcher.useRef(null);
55-
Dispatcher.useMutationEffect(() => {});
5655
Dispatcher.useLayoutEffect(() => {});
5756
Dispatcher.useEffect(() => {});
5857
Dispatcher.useImperativeMethods(undefined, () => null);
@@ -140,18 +139,6 @@ function useRef<T>(initialValue: T): {current: T} {
140139
return ref;
141140
}
142141

143-
function useMutationEffect(
144-
create: () => mixed,
145-
inputs: Array<mixed> | void | null,
146-
): void {
147-
nextHook();
148-
hookLog.push({
149-
primitive: 'MutationEffect',
150-
stackError: new Error(),
151-
value: create,
152-
});
153-
}
154-
155142
function useLayoutEffect(
156143
create: () => mixed,
157144
inputs: Array<mixed> | void | null,
@@ -221,7 +208,6 @@ const Dispatcher = {
221208
useImperativeMethods,
222209
useLayoutEffect,
223210
useMemo,
224-
useMutationEffect,
225211
useReducer,
226212
useRef,
227213
useState,

packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.internal.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('ReactHooksInspection', () => {
129129
return result;
130130
}
131131
function useBaz(value) {
132-
React.useMutationEffect(effect);
132+
React.useLayoutEffect(effect);
133133
let result = useCustom(value);
134134
return result;
135135
}
@@ -176,7 +176,7 @@ describe('ReactHooksInspection', () => {
176176
value: undefined,
177177
subHooks: [
178178
{
179-
name: 'MutationEffect',
179+
name: 'LayoutEffect',
180180
value: effect,
181181
subHooks: [],
182182
},

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.internal.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ describe('ReactHooksInspectionIntergration', () => {
7979
let [state2, dispatch] = React.useReducer((s, a) => a.value, 'b');
8080
let ref = React.useRef('c');
8181

82-
React.useMutationEffect(effect);
8382
React.useLayoutEffect(effect);
8483
React.useEffect(effect);
8584

@@ -117,7 +116,6 @@ describe('ReactHooksInspectionIntergration', () => {
117116
{name: 'State', value: 'a', subHooks: []},
118117
{name: 'Reducer', value: 'b', subHooks: []},
119118
{name: 'Ref', value: 'c', subHooks: []},
120-
{name: 'MutationEffect', value: effect, subHooks: []},
121119
{name: 'LayoutEffect', value: effect, subHooks: []},
122120
{name: 'Effect', value: effect, subHooks: []},
123121
{name: 'ImperativeMethods', value: outsideRef.current, subHooks: []},
@@ -134,7 +132,6 @@ describe('ReactHooksInspectionIntergration', () => {
134132
{name: 'State', value: 'A', subHooks: []},
135133
{name: 'Reducer', value: 'B', subHooks: []},
136134
{name: 'Ref', value: 'C', subHooks: []},
137-
{name: 'MutationEffect', value: effect, subHooks: []},
138135
{name: 'LayoutEffect', value: effect, subHooks: []},
139136
{name: 'Effect', value: effect, subHooks: []},
140137
{name: 'ImperativeMethods', value: outsideRef.current, subHooks: []},

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ let useCallback;
2525
let useMemo;
2626
let useRef;
2727
let useImperativeMethods;
28-
let useMutationEffect;
2928
let useLayoutEffect;
3029
let forwardRef;
3130
let yieldedValues;
@@ -50,7 +49,6 @@ function initModules() {
5049
useMemo = React.useMemo;
5150
useRef = React.useRef;
5251
useImperativeMethods = React.useImperativeMethods;
53-
useMutationEffect = React.useMutationEffect;
5452
useLayoutEffect = React.useLayoutEffect;
5553
forwardRef = React.forwardRef;
5654

@@ -551,22 +549,6 @@ describe('ReactDOMServerHooks', () => {
551549
});
552550
});
553551

554-
describe('useMutationEffect', () => {
555-
it('should warn when invoked during render', async () => {
556-
function Counter() {
557-
useMutationEffect(() => {
558-
throw new Error('should not be invoked');
559-
});
560-
561-
return <Text text="Count: 0" />;
562-
}
563-
const domNode = await serverRender(<Counter />, 1);
564-
expect(clearYields()).toEqual(['Count: 0']);
565-
expect(domNode.tagName).toEqual('SPAN');
566-
expect(domNode.textContent).toEqual('Count: 0');
567-
});
568-
});
569-
570552
describe('useLayoutEffect', () => {
571553
it('should warn when invoked during render', async () => {
572554
function Counter() {

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -271,20 +271,6 @@ function useRef<T>(initialValue: T): {current: T} {
271271
}
272272
}
273273

274-
function useMutationEffect(
275-
create: () => mixed,
276-
inputs: Array<mixed> | void | null,
277-
) {
278-
warning(
279-
false,
280-
'useMutationEffect does nothing on the server, because its effect cannot ' +
281-
"be encoded into the server renderer's output format. This will lead " +
282-
'to a mismatch between the initial, non-hydrated UI and the intended ' +
283-
'UI. To avoid this, useMutationEffect should only be used in ' +
284-
'components that render exclusively on the client.',
285-
);
286-
}
287-
288274
export function useLayoutEffect(
289275
create: () => mixed,
290276
inputs: Array<mixed> | void | null,
@@ -358,7 +344,6 @@ export const Dispatcher = {
358344
useReducer,
359345
useRef,
360346
useState,
361-
useMutationEffect,
362347
useLayoutEffect,
363348
// Callbacks are passed as they are in the server environment.
364349
useCallback: identity,

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,8 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
10871087
case ForwardRef:
10881088
case MemoComponent:
10891089
case SimpleMemoComponent: {
1090+
// Note: We currently never use MountMutation, but useLayout uses
1091+
// UnmountMutation.
10901092
commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10911093
return;
10921094
}
@@ -1101,6 +1103,8 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
11011103
case ForwardRef:
11021104
case MemoComponent:
11031105
case SimpleMemoComponent: {
1106+
// Note: We currently never use MountMutation, but useLayout uses
1107+
// UnmountMutation.
11041108
commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
11051109
return;
11061110
}

packages/react-reconciler/src/ReactFiberDispatcher.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
useImperativeMethods,
1616
useLayoutEffect,
1717
useMemo,
18-
useMutationEffect,
1918
useReducer,
2019
useRef,
2120
useState,
@@ -29,7 +28,6 @@ export const Dispatcher = {
2928
useImperativeMethods,
3029
useLayoutEffect,
3130
useMemo,
32-
useMutationEffect,
3331
useReducer,
3432
useRef,
3533
useState,

packages/react-reconciler/src/ReactFiberHooks.js

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@ import {NoWork} from './ReactFiberExpirationTime';
1616
import {enableHooks} from 'shared/ReactFeatureFlags';
1717
import {readContext} from './ReactFiberNewContext';
1818
import {
19-
Snapshot as SnapshotEffect,
2019
Update as UpdateEffect,
2120
Passive as PassiveEffect,
2221
} from 'shared/ReactSideEffectTags';
2322
import {
2423
NoEffect as NoHookEffect,
25-
UnmountSnapshot,
2624
UnmountMutation,
27-
MountMutation,
2825
MountLayout,
2926
UnmountPassive,
3027
MountPassive,
@@ -517,18 +514,6 @@ export function useRef<T>(initialValue: T): {current: T} {
517514
return ref;
518515
}
519516

520-
export function useMutationEffect(
521-
create: () => mixed,
522-
inputs: Array<mixed> | void | null,
523-
): void {
524-
useEffectImpl(
525-
SnapshotEffect | UpdateEffect,
526-
UnmountSnapshot | MountMutation,
527-
create,
528-
inputs,
529-
);
530-
}
531-
532517
export function useLayoutEffect(
533518
create: () => mixed,
534519
inputs: Array<mixed> | void | null,
@@ -586,26 +571,21 @@ export function useImperativeMethods<T>(
586571
// TODO: I've implemented this on top of useEffect because it's almost the
587572
// same thing, and it would require an equal amount of code. It doesn't seem
588573
// like a common enough use case to justify the additional size.
589-
useEffectImpl(
590-
UpdateEffect,
591-
UnmountMutation | MountLayout,
592-
() => {
593-
if (typeof ref === 'function') {
594-
const refCallback = ref;
595-
const inst = create();
596-
refCallback(inst);
597-
return () => refCallback(null);
598-
} else if (ref !== null && ref !== undefined) {
599-
const refObject = ref;
600-
const inst = create();
601-
refObject.current = inst;
602-
return () => {
603-
refObject.current = null;
604-
};
605-
}
606-
},
607-
nextInputs,
608-
);
574+
useLayoutEffect(() => {
575+
if (typeof ref === 'function') {
576+
const refCallback = ref;
577+
const inst = create();
578+
refCallback(inst);
579+
return () => refCallback(null);
580+
} else if (ref !== null && ref !== undefined) {
581+
const refObject = ref;
582+
const inst = create();
583+
refObject.current = inst;
584+
return () => {
585+
refObject.current = null;
586+
};
587+
}
588+
}, nextInputs);
609589
}
610590

611591
export function useCallback<T>(

0 commit comments

Comments
 (0)