Skip to content

Commit 029f99a

Browse files
committed
Remove event pooling in the modern system
1 parent 2fe0fbb commit 029f99a

File tree

5 files changed

+134
-79
lines changed

5 files changed

+134
-79
lines changed

packages/legacy-events/EventBatching.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import invariant from 'shared/invariant';
10+
import {enableModernEventSystem} from 'shared/ReactFeatureFlags';
1011
import {rethrowCaughtError} from 'shared/ReactErrorUtils';
1112

1213
import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
@@ -30,8 +31,11 @@ const executeDispatchesAndRelease = function(event: ReactSyntheticEvent) {
3031
if (event) {
3132
executeDispatchesInOrder(event);
3233

33-
if (!event.isPersistent()) {
34-
event.constructor.release(event);
34+
// Modern event system doesn't use pooling.
35+
if (!enableModernEventSystem) {
36+
if (!event.isPersistent()) {
37+
event.constructor.release(event);
38+
}
3539
}
3640
}
3741
};

packages/legacy-events/ResponderEventPlugin.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
import {enableModernEventSystem} from 'shared/ReactFeatureFlags';
89
import {getLowestCommonAncestor, isAncestor} from 'shared/ReactTreeTraversal';
910

1011
import {
@@ -378,8 +379,11 @@ function setResponderAndExtractTransfer(
378379
accumulateTwoPhaseDispatches(shouldSetEvent);
379380
}
380381
const wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
381-
if (!shouldSetEvent.isPersistent()) {
382-
shouldSetEvent.constructor.release(shouldSetEvent);
382+
// Modern event system doesn't use pooling.
383+
if (!enableModernEventSystem) {
384+
if (!shouldSetEvent.isPersistent()) {
385+
shouldSetEvent.constructor.release(shouldSetEvent);
386+
}
383387
}
384388

385389
if (!wantsResponderInst || wantsResponderInst === responderInst) {
@@ -409,8 +413,12 @@ function setResponderAndExtractTransfer(
409413
const shouldSwitch =
410414
!hasDispatches(terminationRequestEvent) ||
411415
executeDirectDispatch(terminationRequestEvent);
412-
if (!terminationRequestEvent.isPersistent()) {
413-
terminationRequestEvent.constructor.release(terminationRequestEvent);
416+
417+
// Modern event system doesn't use pooling.
418+
if (!enableModernEventSystem) {
419+
if (!terminationRequestEvent.isPersistent()) {
420+
terminationRequestEvent.constructor.release(terminationRequestEvent);
421+
}
414422
}
415423

416424
if (shouldSwitch) {

packages/legacy-events/SyntheticEvent.js

Lines changed: 94 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import invariant from 'shared/invariant';
1111

12+
import {enableModernEventSystem} from 'shared/ReactFeatureFlags';
13+
1214
const EVENT_POOL_SIZE = 10;
1315

1416
/**
@@ -152,71 +154,79 @@ Object.assign(SyntheticEvent.prototype, {
152154
* won't be added back into the pool.
153155
*/
154156
persist: function() {
155-
this.isPersistent = functionThatReturnsTrue;
157+
// Modern event system doesn't use pooling.
158+
if (!enableModernEventSystem) {
159+
this.isPersistent = functionThatReturnsTrue;
160+
}
156161
},
157162

158163
/**
159164
* Checks if this event should be released back into the pool.
160165
*
161166
* @return {boolean} True if this should not be released, false otherwise.
162167
*/
163-
isPersistent: functionThatReturnsFalse,
168+
isPersistent: enableModernEventSystem
169+
? functionThatReturnsTrue
170+
: functionThatReturnsFalse,
164171

165172
/**
166173
* `PooledClass` looks for `destructor` on each instance it releases.
167174
*/
168175
destructor: function() {
169-
const Interface = this.constructor.Interface;
170-
for (const propName in Interface) {
176+
// Modern event system doesn't use pooling.
177+
if (!enableModernEventSystem) {
178+
const Interface = this.constructor.Interface;
179+
for (const propName in Interface) {
180+
if (__DEV__) {
181+
Object.defineProperty(
182+
this,
183+
propName,
184+
getPooledWarningPropertyDefinition(propName, Interface[propName]),
185+
);
186+
} else {
187+
this[propName] = null;
188+
}
189+
}
190+
this.dispatchConfig = null;
191+
this._targetInst = null;
192+
this.nativeEvent = null;
193+
this.isDefaultPrevented = functionThatReturnsFalse;
194+
this.isPropagationStopped = functionThatReturnsFalse;
195+
this._dispatchListeners = null;
196+
this._dispatchInstances = null;
171197
if (__DEV__) {
172198
Object.defineProperty(
173199
this,
174-
propName,
175-
getPooledWarningPropertyDefinition(propName, Interface[propName]),
200+
'nativeEvent',
201+
getPooledWarningPropertyDefinition('nativeEvent', null),
176202
);
177-
} else {
178-
this[propName] = null;
179-
}
180-
}
181-
this.dispatchConfig = null;
182-
this._targetInst = null;
183-
this.nativeEvent = null;
184-
this.isDefaultPrevented = functionThatReturnsFalse;
185-
this.isPropagationStopped = functionThatReturnsFalse;
186-
this._dispatchListeners = null;
187-
this._dispatchInstances = null;
188-
if (__DEV__) {
189-
Object.defineProperty(
190-
this,
191-
'nativeEvent',
192-
getPooledWarningPropertyDefinition('nativeEvent', null),
193-
);
194-
Object.defineProperty(
195-
this,
196-
'isDefaultPrevented',
197-
getPooledWarningPropertyDefinition(
203+
Object.defineProperty(
204+
this,
198205
'isDefaultPrevented',
199-
functionThatReturnsFalse,
200-
),
201-
);
202-
Object.defineProperty(
203-
this,
204-
'isPropagationStopped',
205-
getPooledWarningPropertyDefinition(
206+
getPooledWarningPropertyDefinition(
207+
'isDefaultPrevented',
208+
functionThatReturnsFalse,
209+
),
210+
);
211+
Object.defineProperty(
212+
this,
206213
'isPropagationStopped',
207-
functionThatReturnsFalse,
208-
),
209-
);
210-
Object.defineProperty(
211-
this,
212-
'preventDefault',
213-
getPooledWarningPropertyDefinition('preventDefault', () => {}),
214-
);
215-
Object.defineProperty(
216-
this,
217-
'stopPropagation',
218-
getPooledWarningPropertyDefinition('stopPropagation', () => {}),
219-
);
214+
getPooledWarningPropertyDefinition(
215+
'isPropagationStopped',
216+
functionThatReturnsFalse,
217+
),
218+
);
219+
Object.defineProperty(
220+
this,
221+
'preventDefault',
222+
getPooledWarningPropertyDefinition('preventDefault', () => {}),
223+
);
224+
Object.defineProperty(
225+
this,
226+
'stopPropagation',
227+
getPooledWarningPropertyDefinition('stopPropagation', () => {}),
228+
);
229+
}
220230
}
221231
},
222232
});
@@ -296,18 +306,26 @@ function getPooledWarningPropertyDefinition(propName, getVal) {
296306
}
297307
}
298308

299-
function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
309+
function createOrGetPooledEvent(
310+
dispatchConfig,
311+
targetInst,
312+
nativeEvent,
313+
nativeInst,
314+
) {
300315
const EventConstructor = this;
301-
if (EventConstructor.eventPool.length) {
302-
const instance = EventConstructor.eventPool.pop();
303-
EventConstructor.call(
304-
instance,
305-
dispatchConfig,
306-
targetInst,
307-
nativeEvent,
308-
nativeInst,
309-
);
310-
return instance;
316+
// Modern event system doesn't use pooling.
317+
if (!enableModernEventSystem) {
318+
if (EventConstructor.eventPool.length) {
319+
const instance = EventConstructor.eventPool.pop();
320+
EventConstructor.call(
321+
instance,
322+
dispatchConfig,
323+
targetInst,
324+
nativeEvent,
325+
nativeInst,
326+
);
327+
return instance;
328+
}
311329
}
312330
return new EventConstructor(
313331
dispatchConfig,
@@ -318,21 +336,28 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
318336
}
319337

320338
function releasePooledEvent(event) {
321-
const EventConstructor = this;
322-
invariant(
323-
event instanceof EventConstructor,
324-
'Trying to release an event instance into a pool of a different type.',
325-
);
326-
event.destructor();
327-
if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
328-
EventConstructor.eventPool.push(event);
339+
// Modern event system doesn't use pooling.
340+
if (!enableModernEventSystem) {
341+
const EventConstructor = this;
342+
invariant(
343+
event instanceof EventConstructor,
344+
'Trying to release an event instance into a pool of a different type.',
345+
);
346+
event.destructor();
347+
if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
348+
EventConstructor.eventPool.push(event);
349+
}
329350
}
330351
}
331352

332353
function addEventPoolingTo(EventConstructor) {
333-
EventConstructor.eventPool = [];
334-
EventConstructor.getPooled = getPooledEvent;
335-
EventConstructor.release = releasePooledEvent;
354+
EventConstructor.getPooled = createOrGetPooledEvent;
355+
356+
// Modern event system doesn't use pooling.
357+
if (!enableModernEventSystem) {
358+
EventConstructor.eventPool = [];
359+
EventConstructor.release = releasePooledEvent;
360+
}
336361
}
337362

338363
export default SyntheticEvent;

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,7 @@ function dispatchEventsForPlugins(
132132
for (let i = 0; i < syntheticEvents.length; i++) {
133133
const syntheticEvent = syntheticEvents[i];
134134
executeDispatchesInOrder(syntheticEvent);
135-
// Release the event from the pool if needed
136-
if (!syntheticEvent.isPersistent()) {
137-
syntheticEvent.constructor.release(syntheticEvent);
138-
}
135+
// This doesn't call release because modern system doesn't use pooling.
139136
}
140137
}
141138

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,25 @@ describe('DOMModernPluginEventSystem', () => {
169169
expect(log).toEqual([]);
170170
expect(onDivClick).toHaveBeenCalledTimes(0);
171171
});
172+
173+
it('does not pool events', () => {
174+
const buttonRef = React.createRef();
175+
const log = [];
176+
const onClick = jest.fn(e => log.push(e));
177+
178+
function Test() {
179+
return <button ref={buttonRef} onClick={onClick} />;
180+
}
181+
182+
ReactDOM.render(<Test />, container);
183+
184+
let buttonElement = buttonRef.current;
185+
dispatchClickEvent(buttonElement);
186+
expect(onClick).toHaveBeenCalledTimes(1);
187+
dispatchClickEvent(buttonElement);
188+
expect(onClick).toHaveBeenCalledTimes(2);
189+
expect(log[0]).not.toBe(log[1]);
190+
expect(log[0].type).toBe('click');
191+
expect(log[1].type).toBe('click');
192+
});
172193
});

0 commit comments

Comments
 (0)