Skip to content

Commit 29fb586

Browse files
authored
Move EventComponent state creation to complete phase + tests (#15352)
1 parent 745baf2 commit 29fb586

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

packages/react-dom/src/events/DOMEventResponderSystem.js

-15
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ type PartialEventObject = {
5656

5757
let currentOwner = null;
5858
let currentFiber: Fiber;
59-
let currentResponder: ReactEventResponder;
6059
let currentEventQueue: EventQueue;
6160

6261
const eventResponderContext: ResponderContext = {
@@ -227,22 +226,18 @@ const eventResponderContext: ResponderContext = {
227226
return false;
228227
},
229228
setTimeout(func: () => void, delay): TimeoutID {
230-
const contextResponder = currentResponder;
231229
const contextFiber = currentFiber;
232230
return setTimeout(() => {
233231
const previousEventQueue = currentEventQueue;
234232
const previousFiber = currentFiber;
235-
const previousResponder = currentResponder;
236233
currentEventQueue = createEventQueue();
237-
currentResponder = contextResponder;
238234
currentFiber = contextFiber;
239235
try {
240236
func();
241237
batchedUpdates(processEventQueue, currentEventQueue);
242238
} finally {
243239
currentFiber = previousFiber;
244240
currentEventQueue = previousEventQueue;
245-
currentResponder = previousResponder;
246241
}
247242
}, delay);
248243
},
@@ -361,19 +356,12 @@ function handleTopLevelType(
361356
}
362357
}
363358
let {props, state} = fiber.stateNode;
364-
if (state === null && responder.createInitialState !== undefined) {
365-
state = fiber.stateNode.state = responder.createInitialState(props);
366-
}
367359
const previousFiber = currentFiber;
368-
const previousResponder = currentResponder;
369360
currentFiber = fiber;
370-
currentResponder = responder;
371-
372361
try {
373362
responder.onEvent(responderEvent, eventResponderContext, props, state);
374363
} finally {
375364
currentFiber = previousFiber;
376-
currentResponder = previousResponder;
377365
}
378366
}
379367

@@ -430,16 +418,13 @@ export function unmountEventResponder(
430418
let {props, state} = fiber.stateNode;
431419
const previousEventQueue = currentEventQueue;
432420
const previousFiber = currentFiber;
433-
const previousResponder = currentResponder;
434421
currentEventQueue = createEventQueue();
435422
currentFiber = fiber;
436-
currentResponder = responder;
437423
try {
438424
onUnmount(eventResponderContext, props, state);
439425
} finally {
440426
currentEventQueue = previousEventQueue;
441427
currentFiber = previousFiber;
442-
currentResponder = previousResponder;
443428
}
444429
}
445430
if (currentOwner === fiber) {

packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js

+41-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ let React;
1313
let ReactFeatureFlags;
1414
let ReactDOM;
1515

16-
function createReactEventComponent(targetEventTypes, onEvent, onUnmount) {
16+
function createReactEventComponent(
17+
targetEventTypes,
18+
createInitialState,
19+
onEvent,
20+
onUnmount,
21+
) {
1722
const testEventResponder = {
1823
targetEventTypes,
24+
createInitialState,
1925
onEvent,
2026
onUnmount,
2127
};
@@ -61,6 +67,7 @@ describe('DOMEventResponderSystem', () => {
6167

6268
const ClickEventComponent = createReactEventComponent(
6369
['click'],
70+
undefined,
6471
(event, context, props) => {
6572
eventResponderFiredCount++;
6673
eventLog.push({
@@ -114,6 +121,7 @@ describe('DOMEventResponderSystem', () => {
114121

115122
const ClickEventComponent = createReactEventComponent(
116123
['click'],
124+
undefined,
117125
(event, context, props) => {
118126
eventLog.push({
119127
name: event.type,
@@ -149,6 +157,7 @@ describe('DOMEventResponderSystem', () => {
149157

150158
const ClickEventComponent = createReactEventComponent(
151159
['click'],
160+
undefined,
152161
(event, context, props) => {
153162
eventResponderFiredCount++;
154163
eventLog.push({
@@ -193,13 +202,15 @@ describe('DOMEventResponderSystem', () => {
193202

194203
const ClickEventComponentA = createReactEventComponent(
195204
['click'],
205+
undefined,
196206
(context, props) => {
197207
eventLog.push('A');
198208
},
199209
);
200210

201211
const ClickEventComponentB = createReactEventComponent(
202212
['click'],
213+
undefined,
203214
(context, props) => {
204215
eventLog.push('B');
205216
},
@@ -228,6 +239,7 @@ describe('DOMEventResponderSystem', () => {
228239

229240
const ClickEventComponent = createReactEventComponent(
230241
['click'],
242+
undefined,
231243
(event, context, props) => {
232244
if (props.onMagicClick) {
233245
const syntheticEvent = {
@@ -265,6 +277,7 @@ describe('DOMEventResponderSystem', () => {
265277

266278
const LongPressEventComponent = createReactEventComponent(
267279
['click'],
280+
undefined,
268281
(event, context, props) => {
269282
const pressEvent = {
270283
listener: props.onPress,
@@ -323,7 +336,8 @@ describe('DOMEventResponderSystem', () => {
323336

324337
const EventComponent = createReactEventComponent(
325338
[],
326-
(event, context, props) => {},
339+
undefined,
340+
(event, context, props, state) => {},
327341
() => {
328342
onUnmountFired++;
329343
},
@@ -339,4 +353,29 @@ describe('DOMEventResponderSystem', () => {
339353
ReactDOM.render(null, container);
340354
expect(onUnmountFired).toEqual(1);
341355
});
356+
357+
it('the event responder onUnmount() function should fire with state', () => {
358+
let counter = 0;
359+
360+
const EventComponent = createReactEventComponent(
361+
[],
362+
() => ({
363+
incrementAmount: 5,
364+
}),
365+
(event, context, props, state) => {},
366+
(context, props, state) => {
367+
counter += state.incrementAmount;
368+
},
369+
);
370+
371+
const Test = () => (
372+
<EventComponent>
373+
<button />
374+
</EventComponent>
375+
);
376+
377+
ReactDOM.render(<Test />, container);
378+
ReactDOM.render(null, container);
379+
expect(counter).toEqual(5);
380+
});
342381
});

packages/react-reconciler/src/ReactFiberCompleteWork.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -774,10 +774,18 @@ function completeWork(
774774
popHostContext(workInProgress);
775775
const rootContainerInstance = getRootHostContainer();
776776
const responder = workInProgress.type.responder;
777+
const stateNode = workInProgress.stateNode;
777778
// Update the props on the event component state node
778-
workInProgress.stateNode.props = newProps;
779+
stateNode.props = newProps;
779780
// Update the root container, so we can properly unmount events at some point
780-
workInProgress.stateNode.rootInstance = rootContainerInstance;
781+
stateNode.rootInstance = rootContainerInstance;
782+
// Initialize event component state if createInitialState exists
783+
if (
784+
stateNode.state === null &&
785+
responder.createInitialState !== undefined
786+
) {
787+
stateNode.state = responder.createInitialState(newProps);
788+
}
781789
handleEventComponent(responder, rootContainerInstance);
782790
}
783791
break;

0 commit comments

Comments
 (0)