@samitouri / QOS-React-2 / commits / fc80772078

[react-events] Ensure updateEventListeners updates in commit phase (#16540)

Dominic Gannaway committed Aug 22, 2019 at 23:58 UTC fc807720780962729df2ad1b0f53258603c020c7
10 files changed +261 -249
packages/react-art/src/ReactARTHostConfig.js
-1
@@ -432,7 +432,6 @@ export function mountResponderInstance(
432 props: Object,
433 state: Object,
434 instance: Object,
435 - rootContainerInstance: Object,
435 ) {
436 throw new Error('Not yet implemented.');
437 }
packages/react-dom/src/client/ReactDOMHostConfig.js
+1 -2
@@ -824,10 +824,9 @@ export function mountResponderInstance(
824 responderProps: Object,
825 responderState: Object,
826 instance: Instance,
827 - rootContainerInstance: Container,
827 ): ReactDOMEventResponderInstance {
828 // Listen to events
830 - const doc = rootContainerInstance.ownerDocument;
829 + const doc = instance.ownerDocument;
830 const documentBody = doc.body || doc;
831 const {
832 rootEventTypes,
packages/react-dom/src/events/DOMEventResponderSystem.js
+9 -5
@@ -12,7 +12,7 @@ import {
12 PASSIVE_NOT_SUPPORTED,
13 } from 'legacy-events/EventSystemFlags';
14 import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
15 -import {HostComponent} from 'shared/ReactWorkTags';
15 +import {HostComponent, SuspenseComponent} from 'shared/ReactWorkTags';
16 import type {EventPriority} from 'shared/ReactTypes';
17 import type {
18 ReactDOMEventResponder,
@@ -32,10 +32,6 @@ import type {Fiber} from 'react-reconciler/src/ReactFiber';
32 import warning from 'shared/warning';
33 import {enableFlareAPI} from 'shared/ReactFeatureFlags';
34 import invariant from 'shared/invariant';
35 -import {
36 - isFiberSuspenseAndTimedOut,
37 - getSuspenseFallbackChild,
38 -} from 'react-reconciler/src/ReactFiberEvents';
35
36 import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
37 import {
@@ -630,6 +626,14 @@ function validateResponderContext(): void {
626 );
627 }
628
629 +function isFiberSuspenseAndTimedOut(fiber: Fiber): boolean {
630 + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
631 +}
632 +
633 +function getSuspenseFallbackChild(fiber: Fiber): Fiber | null {
634 + return ((((fiber.child: any): Fiber).sibling: any): Fiber).child;
635 +}
636 +
637 export function dispatchEventForResponderEventSystem(
638 topLevelType: string,
639 targetFiber: null | Fiber,
packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js
+68 -8
@@ -14,6 +14,7 @@ let ReactFeatureFlags;
14 let ReactDOM;
15 let ReactDOMServer;
16 let ReactTestRenderer;
17 +let Scheduler;
18
19 // FIXME: What should the public API be for setting an event's priority? Right
20 // now it's an enum but is that what we want? Hard coding this for now.
@@ -72,6 +73,7 @@ describe('DOMEventResponderSystem', () => {
73 React = require('react');
74 ReactDOM = require('react-dom');
75 ReactDOMServer = require('react-dom/server');
76 + Scheduler = require('scheduler');
77 container = document.createElement('div');
78 document.body.appendChild(container);
79 });
@@ -811,8 +813,8 @@ describe('DOMEventResponderSystem', () => {
813
814 it('the event responder system should warn on accessing invalid properties', () => {
815 const TestResponder = createEventResponder({
814 - rootEventTypes: ['click'],
815 - onRootEvent: (event, context, props) => {
816 + targetEventTypes: ['click'],
817 + onEvent: (event, context, props) => {
818 const syntheticEvent = {
819 target: event.target,
820 type: 'click',
@@ -823,19 +825,24 @@ describe('DOMEventResponderSystem', () => {
825 });
826
827 let handler;
828 + let buttonRef = React.createRef();
829 const Test = () => {
830 const listener = React.unstable_useResponder(TestResponder, {
831 onClick: handler,
832 });
833
831 - return <button listeners={listener}>Click me!</button>;
834 + return (
835 + <button listeners={listener} ref={buttonRef}>
836 + Click me!
837 + </button>
838 + );
839 };
840 expect(() => {
841 handler = event => {
842 event.preventDefault();
843 };
844 ReactDOM.render(<Test />, container);
838 - dispatchClickEvent(document.body);
845 + dispatchClickEvent(buttonRef.current);
846 }).toWarnDev(
847 'Warning: preventDefault() is not available on event objects created from event responder modules ' +
848 '(React Flare).' +
@@ -847,7 +854,7 @@ describe('DOMEventResponderSystem', () => {
854 event.stopPropagation();
855 };
856 ReactDOM.render(<Test />, container);
850 - dispatchClickEvent(document.body);
857 + dispatchClickEvent(buttonRef.current);
858 }).toWarnDev(
859 'Warning: stopPropagation() is not available on event objects created from event responder modules ' +
860 '(React Flare).' +
@@ -859,7 +866,7 @@ describe('DOMEventResponderSystem', () => {
866 event.isDefaultPrevented();
867 };
868 ReactDOM.render(<Test />, container);
862 - dispatchClickEvent(document.body);
869 + dispatchClickEvent(buttonRef.current);
870 }).toWarnDev(
871 'Warning: isDefaultPrevented() is not available on event objects created from event responder modules ' +
872 '(React Flare).' +
@@ -871,7 +878,7 @@ describe('DOMEventResponderSystem', () => {
878 event.isPropagationStopped();
879 };
880 ReactDOM.render(<Test />, container);
874 - dispatchClickEvent(document.body);
881 + dispatchClickEvent(buttonRef.current);
882 }).toWarnDev(
883 'Warning: isPropagationStopped() is not available on event objects created from event responder modules ' +
884 '(React Flare).' +
@@ -883,7 +890,7 @@ describe('DOMEventResponderSystem', () => {
890 return event.nativeEvent;
891 };
892 ReactDOM.render(<Test />, container);
886 - dispatchClickEvent(document.body);
893 + dispatchClickEvent(buttonRef.current);
894 }).toWarnDev(
895 'Warning: nativeEvent is not available on event objects created from event responder modules ' +
896 '(React Flare).' +
@@ -934,4 +941,57 @@ describe('DOMEventResponderSystem', () => {
941 ReactDOM.render(<Test2 />, container);
942 buttonRef.current.dispatchEvent(createEvent('foobar'));
943 });
944 +
945 + it('should work with concurrent mode updates', async () => {
946 + const log = [];
947 + const TestResponder = createEventResponder({
948 + targetEventTypes: ['click'],
949 + onEvent(event, context, props) {
950 + log.push(props);
951 + },
952 + });
953 + const ref = React.createRef();
954 +
955 + function Test({counter}) {
956 + const listener = React.unstable_useResponder(TestResponder, {counter});
957 +
958 + return (
959 + <button listeners={listener} ref={ref}>
960 + Press me
961 + </button>
962 + );
963 + }
964 +
965 + let root = ReactDOM.unstable_createRoot(container);
966 + let batch = root.createBatch();
967 + batch.render(<Test counter={0} />);
968 + Scheduler.unstable_flushAll();
969 + jest.runAllTimers();
970 + batch.commit();
971 +
972 + // Click the button
973 + dispatchClickEvent(ref.current);
974 + expect(log).toEqual([{counter: 0}]);
975 +
976 + // Clear log
977 + log.length = 0;
978 +
979 + // Increase counter
980 + batch = root.createBatch();
981 + batch.render(<Test counter={1} />);
982 + Scheduler.unstable_flushAll();
983 + jest.runAllTimers();
984 +
985 + // Click the button again
986 + dispatchClickEvent(ref.current);
987 + expect(log).toEqual([{counter: 0}]);
988 +
989 + // Clear log
990 + log.length = 0;
991 +
992 + // Commit
993 + batch.commit();
994 + dispatchClickEvent(ref.current);
995 + expect(log).toEqual([{counter: 1}]);
996 + });
997 });
packages/react-native-renderer/src/ReactFabricHostConfig.js
-1
@@ -449,7 +449,6 @@ export function mountResponderInstance(
449 props: Object,
450 state: Object,
451 instance: Instance,
452 - rootContainerInstance: Container,
452 ) {
453 if (enableFlareAPI) {
454 const {rootEventTypes} = responder;
packages/react-native-renderer/src/ReactNativeHostConfig.js
-1
@@ -501,7 +501,6 @@ export function mountResponderInstance(
501 props: Object,
502 state: Object,
503 instance: Instance,
504 - rootContainerInstance: Container,
504 ) {
505 throw new Error('Not yet implemented.');
506 }
packages/react-reconciler/src/ReactFiberCommitWork.js
+8
@@ -118,6 +118,7 @@ import {
118 } from './ReactHookEffectTags';
119 import {didWarnAboutReassigningProps} from './ReactFiberBeginWork';
120 import {runWithPriority, NormalPriority} from './SchedulerWithReactIntegration';
121 +import {updateEventListeners} from './ReactFiberEvents';
122
123 let didWarnAboutUndefinedSnapshotBeforeUpdate: Set<mixed> | null = null;
124 if (__DEV__) {
@@ -1331,6 +1332,13 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
1332 finishedWork,
1333 );
1334 }
1335 + if (enableFlareAPI) {
1336 + const prevListeners = oldProps.listeners;
1337 + const nextListeners = newProps.listeners;
1338 + if (prevListeners !== nextListeners) {
1339 + updateEventListeners(nextListeners, instance, finishedWork);
1340 + }
1341 + }
1342 }
1343 return;
1344 }
packages/react-reconciler/src/ReactFiberCompleteWork.js
+5 -186
@@ -9,12 +9,7 @@
9
10 import type {Fiber} from './ReactFiber';
11 import type {ExpirationTime} from './ReactFiberExpirationTime';
12 -import type {
13 - ReactEventResponder,
14 - ReactEventResponderInstance,
15 - ReactFundamentalComponentInstance,
16 - ReactEventResponderListener,
17 -} from 'shared/ReactTypes';
12 +import type {ReactFundamentalComponentInstance} from 'shared/ReactTypes';
13 import type {FiberRoot} from './ReactFiberRoot';
14 import type {
15 Instance,
@@ -31,7 +26,6 @@ import type {SuspenseContext} from './ReactFiberSuspenseContext';
26
27 import {now} from './SchedulerWithReactIntegration';
28
34 -import {REACT_RESPONDER_TYPE} from 'shared/ReactSymbols';
29 import {
30 IndeterminateComponent,
31 FunctionComponent,
@@ -78,8 +72,6 @@ import {
72 createContainerChildSet,
73 appendChildToContainerChildSet,
74 finalizeContainerChildren,
81 - mountResponderInstance,
82 - unmountResponderInstance,
75 getFundamentalComponentInstance,
76 mountFundamentalComponent,
77 cloneFundamentalInstance,
@@ -91,8 +83,6 @@ import {
83 getHostContext,
84 popHostContainer,
85 } from './ReactFiberHostContext';
94 -import {NoWork} from './ReactFiberExpirationTime';
95 -import {createResponderInstance} from './ReactFiberEvents';
86 import {
87 suspenseStackCursor,
88 InvisibleParentSuspenseContext,
@@ -132,10 +122,7 @@ import {
122 import {createFundamentalStateInstance} from './ReactFiberFundamental';
123 import {Never} from './ReactFiberExpirationTime';
124 import {resetChildFibers} from './ReactChildFiber';
135 -import warning from 'shared/warning';
136 -
137 -const emptyObject = {};
138 -const isArray = Array.isArray;
125 +import {updateEventListeners} from './ReactFiberEvents';
126
127 function markUpdate(workInProgress: Fiber) {
128 // Tag the fiber with an update effect. This turns a Placement into
@@ -689,14 +676,8 @@ function completeWork(
676 if (enableFlareAPI) {
677 const prevListeners = current.memoizedProps.listeners;
678 const nextListeners = newProps.listeners;
692 - const instance = workInProgress.stateNode;
679 if (prevListeners !== nextListeners) {
694 - updateEventListeners(
695 - nextListeners,
696 - instance,
697 - rootContainerInstance,
698 - workInProgress,
699 - );
680 + markUpdate(workInProgress);
681 }
682 }
683
@@ -738,12 +719,7 @@ function completeWork(
719 const instance = workInProgress.stateNode;
720 const listeners = newProps.listeners;
721 if (listeners != null) {
741 - updateEventListeners(
742 - listeners,
743 - instance,
744 - rootContainerInstance,
745 - workInProgress,
746 - );
722 + updateEventListeners(listeners, instance, workInProgress);
723 }
724 }
725 } else {
@@ -760,12 +736,7 @@ function completeWork(
736 if (enableFlareAPI) {
737 const listeners = newProps.listeners;
738 if (listeners != null) {
763 - updateEventListeners(
764 - listeners,
765 - instance,
766 - rootContainerInstance,
767 - workInProgress,
768 - );
739 + updateEventListeners(listeners, instance, workInProgress);
740 }
741 }
742
@@ -1253,156 +1224,4 @@ function completeWork(
1224 return null;
1225 }
1226
1256 -function mountEventResponder(
1257 - responder: ReactEventResponder<any, any>,
1258 - responderProps: Object,
1259 - instance: Instance,
1260 - rootContainerInstance: Container,
1261 - fiber: Fiber,
1262 - respondersMap: Map<
1263 - ReactEventResponder<any, any>,
1264 - ReactEventResponderInstance<any, any>,
1265 - >,
1266 -) {
1267 - let responderState = emptyObject;
1268 - const getInitialState = responder.getInitialState;
1269 - if (getInitialState !== null) {
1270 - responderState = getInitialState(responderProps);
1271 - }
1272 - const responderInstance = createResponderInstance(
1273 - responder,
1274 - responderProps,
1275 - responderState,
1276 - instance,
1277 - fiber,
1278 - );
1279 - mountResponderInstance(
1280 - responder,
1281 - responderInstance,
1282 - responderProps,
1283 - responderState,
1284 - instance,
1285 - rootContainerInstance,
1286 - );
1287 - respondersMap.set(responder, responderInstance);
1288 -}
1289 -
1290 -function updateEventListener(
1291 - listener: ReactEventResponderListener<any, any>,
1292 - fiber: Fiber,
1293 - visistedResponders: Set<ReactEventResponder<any, any>>,
1294 - respondersMap: Map<
1295 - ReactEventResponder<any, any>,
1296 - ReactEventResponderInstance<any, any>,
1297 - >,
1298 - instance: Instance,
1299 - rootContainerInstance: Container,
1300 -): void {
1301 - let responder;
1302 - let props;
1303 -
1304 - if (listener) {
1305 - responder = listener.responder;
1306 - props = listener.props;
1307 - }
1308 - invariant(
1309 - responder && responder.$$typeof === REACT_RESPONDER_TYPE,
1310 - 'An invalid value was used as an event listener. Expect one or many event ' +
1311 - 'listeners created via React.unstable_useResponder().',
1312 - );
1313 - const listenerProps = ((props: any): Object);
1314 - if (visistedResponders.has(responder)) {
1315 - // show warning
1316 - if (__DEV__) {
1317 - warning(
1318 - false,
1319 - 'Duplicate event responder "%s" found in event listeners. ' +
1320 - 'Event listeners passed to elements cannot use the same event responder more than once.',
1321 - responder.displayName,
1322 - );
1323 - }
1324 - return;
1325 - }
1326 - visistedResponders.add(responder);
1327 - const responderInstance = respondersMap.get(responder);
1328 -
1329 - if (responderInstance === undefined) {
1330 - // Mount
1331 - mountEventResponder(
1332 - responder,
1333 - listenerProps,
1334 - instance,
1335 - rootContainerInstance,
1336 - fiber,
1337 - respondersMap,
1338 - );
1339 - } else {
1340 - // Update
1341 - responderInstance.props = listenerProps;
1342 - responderInstance.fiber = fiber;
1343 - }
1344 -}
1345 -
1346 -function updateEventListeners(
1347 - listeners: any,
1348 - instance: Instance,
1349 - rootContainerInstance: Container,
1350 - fiber: Fiber,
1351 -): void {
1352 - const visistedResponders = new Set();
1353 - let dependencies = fiber.dependencies;
1354 - if (listeners != null) {
1355 - if (dependencies === null) {
1356 - dependencies = fiber.dependencies = {
1357 - expirationTime: NoWork,
1358 - firstContext: null,
1359 - responders: new Map(),
1360 - };
1361 - }
1362 - let respondersMap = dependencies.responders;
1363 - if (respondersMap === null) {
1364 - respondersMap = new Map();
1365 - }
1366 - if (isArray(listeners)) {
1367 - for (let i = 0, length = listeners.length; i < length; i++) {
1368 - const listener = listeners[i];
1369 - updateEventListener(
1370 - listener,
1371 - fiber,
1372 - visistedResponders,
1373 - respondersMap,
1374 - instance,
1375 - rootContainerInstance,
1376 - );
1377 - }
1378 - } else {
1379 - updateEventListener(
1380 - listeners,
1381 - fiber,
1382 - visistedResponders,
1383 - respondersMap,
1384 - instance,
1385 - rootContainerInstance,
1386 - );
1387 - }
1388 - }
1389 - if (dependencies !== null) {
1390 - const respondersMap = dependencies.responders;
1391 - if (respondersMap !== null) {
1392 - // Unmount
1393 - const mountedResponders = Array.from(respondersMap.keys());
1394 - for (let i = 0, length = mountedResponders.length; i < length; i++) {
1395 - const mountedResponder = mountedResponders[i];
1396 - if (!visistedResponders.has(mountedResponder)) {
1397 - const responderInstance = ((respondersMap.get(
1398 - mountedResponder,
1399 - ): any): ReactEventResponderInstance<any, any>);
1400 - unmountResponderInstance(responderInstance);
1401 - respondersMap.delete(mountedResponder);
1402 - }
1403 - }
1404 - }
1405 - }
1406 -}
1407 -
1227 export {completeWork};
packages/react-reconciler/src/ReactFiberEvents.js
+170 -44
@@ -8,59 +8,26 @@
8 */
9
10 import type {Fiber} from './ReactFiber';
11 +import type {Instance} from './ReactFiberHostConfig';
12 import type {
13 ReactEventResponder,
14 ReactEventResponderInstance,
15 ReactEventResponderListener,
16 } from 'shared/ReactTypes';
16 -import type {Instance} from './ReactFiberHostConfig';
17
18 -import {SuspenseComponent, Fragment} from 'shared/ReactWorkTags';
18 +import {
19 + mountResponderInstance,
20 + unmountResponderInstance,
21 +} from './ReactFiberHostConfig';
22 +import {NoWork} from './ReactFiberExpirationTime';
23
20 -export function createResponderListener(
21 - responder: ReactEventResponder<any, any>,
22 - props: Object,
23 -): ReactEventResponderListener<any, any> {
24 - const eventResponderListener = {
25 - responder,
26 - props,
27 - };
28 - if (__DEV__) {
29 - Object.freeze(eventResponderListener);
30 - }
31 - return eventResponderListener;
32 -}
24 +import warning from 'shared/warning';
25 +import {REACT_RESPONDER_TYPE} from 'shared/ReactSymbols';
26
34 -export function isFiberSuspenseAndTimedOut(fiber: Fiber): boolean {
35 - return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
36 -}
27 +import invariant from 'shared/invariant';
28
38 -export function getSuspenseFallbackChild(fiber: Fiber): Fiber | null {
39 - return ((((fiber.child: any): Fiber).sibling: any): Fiber).child;
40 -}
41 -
42 -export function isFiberSuspenseTimedOutChild(fiber: Fiber | null): boolean {
43 - if (fiber === null) {
44 - return false;
45 - }
46 - const parent = fiber.return;
47 - if (parent !== null && parent.tag === Fragment) {
48 - const grandParent = parent.return;
49 -
50 - if (
51 - grandParent !== null &&
52 - grandParent.tag === SuspenseComponent &&
53 - grandParent.stateNode !== null
54 - ) {
55 - return true;
56 - }
57 - }
58 - return false;
59 -}
60 -
61 -export function getSuspenseFiberFromTimedOutChild(fiber: Fiber): Fiber {
62 - return ((((fiber.return: any): Fiber).return: any): Fiber);
63 -}
29 +const emptyObject = {};
30 +const isArray = Array.isArray;
31
32 export function createResponderInstance(
33 responder: ReactEventResponder<any, any>,
@@ -78,3 +45,162 @@ export function createResponderInstance(
45 target,
46 };
47 }
48 +
49 +function mountEventResponder(
50 + responder: ReactEventResponder<any, any>,
51 + responderProps: Object,
52 + instance: Instance,
53 + fiber: Fiber,
54 + respondersMap: Map<
55 + ReactEventResponder<any, any>,
56 + ReactEventResponderInstance<any, any>,
57 + >,
58 +) {
59 + let responderState = emptyObject;
60 + const getInitialState = responder.getInitialState;
61 + if (getInitialState !== null) {
62 + responderState = getInitialState(responderProps);
63 + }
64 + const responderInstance = createResponderInstance(
65 + responder,
66 + responderProps,
67 + responderState,
68 + instance,
69 + fiber,
70 + );
71 + mountResponderInstance(
72 + responder,
73 + responderInstance,
74 + responderProps,
75 + responderState,
76 + instance,
77 + );
78 + respondersMap.set(responder, responderInstance);
79 +}
80 +
81 +function updateEventListener(
82 + listener: ReactEventResponderListener<any, any>,
83 + fiber: Fiber,
84 + visistedResponders: Set<ReactEventResponder<any, any>>,
85 + respondersMap: Map<
86 + ReactEventResponder<any, any>,
87 + ReactEventResponderInstance<any, any>,
88 + >,
89 + instance: Instance,
90 +): void {
91 + let responder;
92 + let props;
93 +
94 + if (listener) {
95 + responder = listener.responder;
96 + props = listener.props;
97 + }
98 + invariant(
99 + responder && responder.$$typeof === REACT_RESPONDER_TYPE,
100 + 'An invalid value was used as an event listener. Expect one or many event ' +
101 + 'listeners created via React.unstable_useResponder().',
102 + );
103 + const listenerProps = ((props: any): Object);
104 + if (visistedResponders.has(responder)) {
105 + // show warning
106 + if (__DEV__) {
107 + warning(
108 + false,
109 + 'Duplicate event responder "%s" found in event listeners. ' +
110 + 'Event listeners passed to elements cannot use the same event responder more than once.',
111 + responder.displayName,
112 + );
113 + }
114 + return;
115 + }
116 + visistedResponders.add(responder);
117 + const responderInstance = respondersMap.get(responder);
118 +
119 + if (responderInstance === undefined) {
120 + // Mount (happens in either complete or commit phase)
121 + mountEventResponder(
122 + responder,
123 + listenerProps,
124 + instance,
125 + fiber,
126 + respondersMap,
127 + );
128 + } else {
129 + // Update (happens during commit phase only)
130 + responderInstance.props = listenerProps;
131 + responderInstance.fiber = fiber;
132 + }
133 +}
134 +
135 +export function updateEventListeners(
136 + listeners: any,
137 + instance: Instance,
138 + fiber: Fiber,
139 +): void {
140 + const visistedResponders = new Set();
141 + let dependencies = fiber.dependencies;
142 + if (listeners != null) {
143 + if (dependencies === null) {
144 + dependencies = fiber.dependencies = {
145 + expirationTime: NoWork,
146 + firstContext: null,
147 + responders: new Map(),
148 + };
149 + }
150 + let respondersMap = dependencies.responders;
151 + if (respondersMap === null) {
152 + respondersMap = new Map();
153 + }
154 + if (isArray(listeners)) {
155 + for (let i = 0, length = listeners.length; i < length; i++) {
156 + const listener = listeners[i];
157 + updateEventListener(
158 + listener,
159 + fiber,
160 + visistedResponders,
161 + respondersMap,
162 + instance,
163 + );
164 + }
165 + } else {
166 + updateEventListener(
167 + listeners,
168 + fiber,
169 + visistedResponders,
170 + respondersMap,
171 + instance,
172 + );
173 + }
174 + }
175 + if (dependencies !== null) {
176 + const respondersMap = dependencies.responders;
177 + if (respondersMap !== null) {
178 + // Unmount
179 + const mountedResponders = Array.from(respondersMap.keys());
180 + for (let i = 0, length = mountedResponders.length; i < length; i++) {
181 + const mountedResponder = mountedResponders[i];
182 + if (!visistedResponders.has(mountedResponder)) {
183 + const responderInstance = ((respondersMap.get(
184 + mountedResponder,
185 + ): any): ReactEventResponderInstance<any, any>);
186 + unmountResponderInstance(responderInstance);
187 + respondersMap.delete(mountedResponder);
188 + }
189 + }
190 + }
191 + }
192 +}
193 +
194 +export function createResponderListener(
195 + responder: ReactEventResponder<any, any>,
196 + props: Object,
197 +): ReactEventResponderListener<any, any> {
198 + const eventResponderListener = {
199 + responder,
200 + props,
201 + };
202 + if (__DEV__) {
203 + Object.freeze(eventResponderListener);
204 + }
205 + return eventResponderListener;
206 +}
packages/react-test-renderer/src/ReactTestHostConfig.js
-1
@@ -296,7 +296,6 @@ export function mountResponderInstance(
296 props: Object,
297 state: Object,
298 instance: Instance,
299 - rootContainerInstance: Container,
299 ) {
300 // noop
301 }