@samitouri / QOS-React / commits / 29fb5862fb

Move EventComponent state creation to complete phase + tests (#15352)

Dominic Gannaway committed Apr 8, 2019 at 16:02 UTC 29fb5862fb5f7896331d53c631b77a0c0e03a7c2
3 files changed +51 -19
packages/react-dom/src/events/DOMEventResponderSystem.js
-15
@@ -56,7 +56,6 @@ type PartialEventObject = {
56
57 let currentOwner = null;
58 let currentFiber: Fiber;
59 -let currentResponder: ReactEventResponder;
59 let currentEventQueue: EventQueue;
60
61 const eventResponderContext: ResponderContext = {
@@ -227,14 +226,11 @@ const eventResponderContext: ResponderContext = {
226 return false;
227 },
228 setTimeout(func: () => void, delay): TimeoutID {
230 - const contextResponder = currentResponder;
229 const contextFiber = currentFiber;
230 return setTimeout(() => {
231 const previousEventQueue = currentEventQueue;
232 const previousFiber = currentFiber;
235 - const previousResponder = currentResponder;
233 currentEventQueue = createEventQueue();
237 - currentResponder = contextResponder;
234 currentFiber = contextFiber;
235 try {
236 func();
@@ -242,7 +238,6 @@ const eventResponderContext: ResponderContext = {
238 } finally {
239 currentFiber = previousFiber;
240 currentEventQueue = previousEventQueue;
245 - currentResponder = previousResponder;
241 }
242 }, delay);
243 },
@@ -361,19 +356,12 @@ function handleTopLevelType(
356 }
357 }
358 let {props, state} = fiber.stateNode;
364 - if (state === null && responder.createInitialState !== undefined) {
365 - state = fiber.stateNode.state = responder.createInitialState(props);
366 - }
359 const previousFiber = currentFiber;
368 - const previousResponder = currentResponder;
360 currentFiber = fiber;
370 - currentResponder = responder;
371 -
361 try {
362 responder.onEvent(responderEvent, eventResponderContext, props, state);
363 } finally {
364 currentFiber = previousFiber;
376 - currentResponder = previousResponder;
365 }
366 }
367
@@ -430,16 +418,13 @@ export function unmountEventResponder(
418 let {props, state} = fiber.stateNode;
419 const previousEventQueue = currentEventQueue;
420 const previousFiber = currentFiber;
433 - const previousResponder = currentResponder;
421 currentEventQueue = createEventQueue();
422 currentFiber = fiber;
436 - currentResponder = responder;
423 try {
424 onUnmount(eventResponderContext, props, state);
425 } finally {
426 currentEventQueue = previousEventQueue;
427 currentFiber = previousFiber;
442 - currentResponder = previousResponder;
428 }
429 }
430 if (currentOwner === fiber) {
packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js
+41 -2
@@ -13,9 +13,15 @@ let React;
13 let ReactFeatureFlags;
14 let ReactDOM;
15
16 -function createReactEventComponent(targetEventTypes, onEvent, onUnmount) {
16 +function createReactEventComponent(
17 + targetEventTypes,
18 + createInitialState,
19 + onEvent,
20 + onUnmount,
21 +) {
22 const testEventResponder = {
23 targetEventTypes,
24 + createInitialState,
25 onEvent,
26 onUnmount,
27 };
@@ -61,6 +67,7 @@ describe('DOMEventResponderSystem', () => {
67
68 const ClickEventComponent = createReactEventComponent(
69 ['click'],
70 + undefined,
71 (event, context, props) => {
72 eventResponderFiredCount++;
73 eventLog.push({
@@ -114,6 +121,7 @@ describe('DOMEventResponderSystem', () => {
121
122 const ClickEventComponent = createReactEventComponent(
123 ['click'],
124 + undefined,
125 (event, context, props) => {
126 eventLog.push({
127 name: event.type,
@@ -149,6 +157,7 @@ describe('DOMEventResponderSystem', () => {
157
158 const ClickEventComponent = createReactEventComponent(
159 ['click'],
160 + undefined,
161 (event, context, props) => {
162 eventResponderFiredCount++;
163 eventLog.push({
@@ -193,6 +202,7 @@ describe('DOMEventResponderSystem', () => {
202
203 const ClickEventComponentA = createReactEventComponent(
204 ['click'],
205 + undefined,
206 (context, props) => {
207 eventLog.push('A');
208 },
@@ -200,6 +210,7 @@ describe('DOMEventResponderSystem', () => {
210
211 const ClickEventComponentB = createReactEventComponent(
212 ['click'],
213 + undefined,
214 (context, props) => {
215 eventLog.push('B');
216 },
@@ -228,6 +239,7 @@ describe('DOMEventResponderSystem', () => {
239
240 const ClickEventComponent = createReactEventComponent(
241 ['click'],
242 + undefined,
243 (event, context, props) => {
244 if (props.onMagicClick) {
245 const syntheticEvent = {
@@ -265,6 +277,7 @@ describe('DOMEventResponderSystem', () => {
277
278 const LongPressEventComponent = createReactEventComponent(
279 ['click'],
280 + undefined,
281 (event, context, props) => {
282 const pressEvent = {
283 listener: props.onPress,
@@ -323,7 +336,8 @@ describe('DOMEventResponderSystem', () => {
336
337 const EventComponent = createReactEventComponent(
338 [],
326 - (event, context, props) => {},
339 + undefined,
340 + (event, context, props, state) => {},
341 () => {
342 onUnmountFired++;
343 },
@@ -339,4 +353,29 @@ describe('DOMEventResponderSystem', () => {
353 ReactDOM.render(null, container);
354 expect(onUnmountFired).toEqual(1);
355 });
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 + });
381 });
packages/react-reconciler/src/ReactFiberCompleteWork.js
+10 -2
@@ -774,10 +774,18 @@ function completeWork(
774 popHostContext(workInProgress);
775 const rootContainerInstance = getRootHostContainer();
776 const responder = workInProgress.type.responder;
777 + const stateNode = workInProgress.stateNode;
778 // Update the props on the event component state node
778 - workInProgress.stateNode.props = newProps;
779 + stateNode.props = newProps;
780 // 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 + }
789 handleEventComponent(responder, rootContainerInstance);
790 }
791 break;