Skip to content

Commit c8ab997

Browse files
committed
Inline event function wrapping
- Inlines wrapping of the callback - Use a mutable ref-style object instead of a callable object - Fix types
1 parent ef85a49 commit c8ab997

File tree

6 files changed

+92
-113
lines changed

6 files changed

+92
-113
lines changed

packages/react-reconciler/src/ReactFiberCommitWork.new.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ import type {
1515
ChildSet,
1616
UpdatePayload,
1717
} from './ReactFiberHostConfig';
18-
import type {
19-
Fiber,
20-
FiberRoot,
21-
EventFunctionWrapper,
22-
} from './ReactInternalTypes';
18+
import type {Fiber, FiberRoot} from './ReactInternalTypes';
2319
import type {Lanes} from './ReactFiberLane.new';
2420
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
2521
import type {UpdateQueue} from './ReactFiberClassUpdateQueue.new';
@@ -689,13 +685,9 @@ function commitUseEventMount(finishedWork: Fiber) {
689685
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
690686
const eventPayloads = updateQueue !== null ? updateQueue.events : null;
691687
if (eventPayloads !== null) {
692-
// FunctionComponentUpdateQueue.events is a flat array of
693-
// [EventFunctionWrapper, EventFunction, ...], so increment by 2 each iteration to find the next
694-
// pair.
695-
for (let ii = 0; ii < eventPayloads.length; ii += 2) {
696-
const eventFn: EventFunctionWrapper<any, any, any> = eventPayloads[ii];
697-
const nextImpl = eventPayloads[ii + 1];
698-
eventFn._impl = nextImpl;
688+
for (let ii = 0; ii < eventPayloads.length; ii++) {
689+
const {ref, nextImpl} = eventPayloads[ii];
690+
ref.impl = nextImpl;
699691
}
700692
}
701693
}

packages/react-reconciler/src/ReactFiberCommitWork.old.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ import type {
1515
ChildSet,
1616
UpdatePayload,
1717
} from './ReactFiberHostConfig';
18-
import type {
19-
Fiber,
20-
FiberRoot,
21-
EventFunctionWrapper,
22-
} from './ReactInternalTypes';
18+
import type {Fiber, FiberRoot} from './ReactInternalTypes';
2319
import type {Lanes} from './ReactFiberLane.old';
2420
import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
2521
import type {UpdateQueue} from './ReactFiberClassUpdateQueue.old';
@@ -689,13 +685,9 @@ function commitUseEventMount(finishedWork: Fiber) {
689685
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
690686
const eventPayloads = updateQueue !== null ? updateQueue.events : null;
691687
if (eventPayloads !== null) {
692-
// FunctionComponentUpdateQueue.events is a flat array of
693-
// [EventFunctionWrapper, EventFunction, ...], so increment by 2 each iteration to find the next
694-
// pair.
695-
for (let ii = 0; ii < eventPayloads.length; ii += 2) {
696-
const eventFn: EventFunctionWrapper<any, any, any> = eventPayloads[ii];
697-
const nextImpl = eventPayloads[ii + 1];
698-
eventFn._impl = nextImpl;
688+
for (let ii = 0; ii < eventPayloads.length; ii++) {
689+
const {ref, nextImpl} = eventPayloads[ii];
690+
ref.impl = nextImpl;
699691
}
700692
}
701693
}

packages/react-reconciler/src/ReactFiberHooks.new.js

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import type {
2222
Dispatcher,
2323
HookType,
2424
MemoCache,
25-
EventFunctionWrapper,
2625
} from './ReactInternalTypes';
2726
import type {Lanes, Lane} from './ReactFiberLane.new';
2827
import type {HookFlags} from './ReactHookEffectTags';
@@ -189,9 +188,17 @@ type StoreConsistencyCheck<T> = {
189188
getSnapshot: () => T,
190189
};
191190

191+
type EventFunctionPayload<Args, Return, F: (...Array<Args>) => Return> = {
192+
ref: {
193+
eventFn: F,
194+
impl: F,
195+
},
196+
nextImpl: F,
197+
};
198+
192199
export type FunctionComponentUpdateQueue = {
193200
lastEffect: Effect | null,
194-
events: Array<() => mixed> | null,
201+
events: Array<EventFunctionPayload<any, any, any>> | null,
195202
stores: Array<StoreConsistencyCheck<any>> | null,
196203
// NOTE: optional, only set when enableUseMemoCacheHook is enabled
197204
memoCache?: MemoCache | null,
@@ -1909,58 +1916,56 @@ function updateEffect(
19091916
}
19101917

19111918
function useEventImpl<Args, Return, F: (...Array<Args>) => Return>(
1912-
event: EventFunctionWrapper<Args, Return, F>,
1913-
nextImpl: F,
1919+
payload: EventFunctionPayload<Args, Return, F>,
19141920
) {
19151921
currentlyRenderingFiber.flags |= UpdateEffect;
19161922
let componentUpdateQueue: null | FunctionComponentUpdateQueue = (currentlyRenderingFiber.updateQueue: any);
19171923
if (componentUpdateQueue === null) {
19181924
componentUpdateQueue = createFunctionComponentUpdateQueue();
19191925
currentlyRenderingFiber.updateQueue = (componentUpdateQueue: any);
1920-
componentUpdateQueue.events = [event, nextImpl];
1926+
componentUpdateQueue.events = [payload];
19211927
} else {
19221928
const events = componentUpdateQueue.events;
19231929
if (events === null) {
1924-
componentUpdateQueue.events = [event, nextImpl];
1930+
componentUpdateQueue.events = [payload];
19251931
} else {
1926-
events.push(event, nextImpl);
1932+
events.push(payload);
19271933
}
19281934
}
19291935
}
19301936

1931-
function wrapEventFunction<Args, Return, F: (...Array<Args>) => Return>(
1937+
function mountEvent<Args, Return, F: (...Array<Args>) => Return>(
19321938
callback: F,
1933-
): EventFunctionWrapper<Args, Return, F> {
1934-
const eventFn: EventFunctionWrapper<Args, Return, F> = function eventFn() {
1939+
): F {
1940+
const hook = mountWorkInProgressHook();
1941+
const ref = {impl: callback};
1942+
hook.memoizedState = ref;
1943+
// $FlowIgnore[incompatible-return]
1944+
return function eventFn() {
19351945
if (isInvalidExecutionContextForEventFunction()) {
19361946
throw new Error(
19371947
"A function wrapped in useEvent can't be called during rendering.",
19381948
);
19391949
}
1940-
// $FlowFixMe[prop-missing] found when upgrading Flow
1941-
return eventFn._impl.apply(undefined, arguments);
1950+
return ref.impl.apply(undefined, arguments);
19421951
};
1943-
eventFn._impl = callback;
1944-
return eventFn;
1945-
}
1946-
1947-
function mountEvent<Args, Return, F: (...Array<Args>) => Return>(
1948-
callback: F,
1949-
): EventFunctionWrapper<Args, Return, F> {
1950-
const hook = mountWorkInProgressHook();
1951-
const eventFn = wrapEventFunction(callback);
1952-
hook.memoizedState = eventFn;
1953-
return eventFn;
19541952
}
19551953

19561954
function updateEvent<Args, Return, F: (...Array<Args>) => Return>(
19571955
callback: F,
1958-
): EventFunctionWrapper<Args, Return, F> {
1956+
): F {
19591957
const hook = updateWorkInProgressHook();
1960-
const eventFn = hook.memoizedState;
1961-
useEventImpl(eventFn, callback);
1962-
// Always return a new function
1963-
return wrapEventFunction(callback);
1958+
const ref = hook.memoizedState;
1959+
useEventImpl({ref, nextImpl: callback});
1960+
// $FlowIgnore[incompatible-return]
1961+
return function eventFn() {
1962+
if (isInvalidExecutionContextForEventFunction()) {
1963+
throw new Error(
1964+
"A function wrapped in useEvent can't be called during rendering.",
1965+
);
1966+
}
1967+
return ref.impl.apply(undefined, arguments);
1968+
};
19641969
}
19651970

19661971
function mountInsertionEffect(
@@ -2922,7 +2927,7 @@ if (__DEV__) {
29222927
Args,
29232928
Return,
29242929
F: (...Array<Args>) => Return,
2925-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
2930+
>(callback: F): F {
29262931
currentHookNameInDev = 'useEvent';
29272932
mountHookTypesDev();
29282933
return mountEvent(callback);
@@ -3079,7 +3084,7 @@ if (__DEV__) {
30793084
Args,
30803085
Return,
30813086
F: (...Array<Args>) => Return,
3082-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3087+
>(callback: F): F {
30833088
currentHookNameInDev = 'useEvent';
30843089
updateHookTypesDev();
30853090
return mountEvent(callback);
@@ -3236,7 +3241,7 @@ if (__DEV__) {
32363241
Args,
32373242
Return,
32383243
F: (...Array<Args>) => Return,
3239-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3244+
>(callback: F): F {
32403245
currentHookNameInDev = 'useEvent';
32413246
updateHookTypesDev();
32423247
return updateEvent(callback);
@@ -3394,7 +3399,7 @@ if (__DEV__) {
33943399
Args,
33953400
Return,
33963401
F: (...Array<Args>) => Return,
3397-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3402+
>(callback: F): F {
33983403
currentHookNameInDev = 'useEvent';
33993404
updateHookTypesDev();
34003405
return updateEvent(callback);
@@ -3578,7 +3583,7 @@ if (__DEV__) {
35783583
Args,
35793584
Return,
35803585
F: (...Array<Args>) => Return,
3581-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3586+
>(callback: F): F {
35823587
currentHookNameInDev = 'useEvent';
35833588
warnInvalidHookAccess();
35843589
mountHookTypesDev();
@@ -3763,7 +3768,7 @@ if (__DEV__) {
37633768
Args,
37643769
Return,
37653770
F: (...Array<Args>) => Return,
3766-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3771+
>(callback: F): F {
37673772
currentHookNameInDev = 'useEvent';
37683773
warnInvalidHookAccess();
37693774
updateHookTypesDev();
@@ -3949,7 +3954,7 @@ if (__DEV__) {
39493954
Args,
39503955
Return,
39513956
F: (...Array<Args>) => Return,
3952-
>(callback: F): EventFunctionWrapper<Args, Return, F> {
3957+
>(callback: F): F {
39533958
currentHookNameInDev = 'useEvent';
39543959
warnInvalidHookAccess();
39553960
updateHookTypesDev();

0 commit comments

Comments
 (0)