Prevent BeforeInputPlugin from returning [null, null] (#11848)
The BeforeInputPlugin dispatches null elements in an array if composition or beforeInput events are not extracted. This causes a an extra array allocation, but more importantly creates null states in later event dispatch methods that are annoying to account for. This commit makes it so that BeforeInputPlugin never returns a null element inside an array.
Nathan Hunzaker committed
Dec 13, 2017 at 20:39 UTC
cc52e06b490e0dc2482b345aa5d0d65fae931095
2 files changed
+44
-62
packages/react-dom/src/events/BeforeInputEventPlugin.js
+23
-14
@@ -453,20 +453,29 @@ const BeforeInputEventPlugin = {
453
nativeEvent,
454
nativeEventTarget,
455
) {
456
- return [
457
- extractCompositionEvent(
458
- topLevelType,
459
- targetInst,
460
- nativeEvent,
461
- nativeEventTarget,
462
- ),
463
- extractBeforeInputEvent(
464
- topLevelType,
465
- targetInst,
466
- nativeEvent,
467
- nativeEventTarget,
468
- ),
469
- ];
456
+ const composition = extractCompositionEvent(
457
+ topLevelType,
458
+ targetInst,
459
+ nativeEvent,
460
+ nativeEventTarget,
461
+ );
462
+
463
+ const beforeInput = extractBeforeInputEvent(
464
+ topLevelType,
465
+ targetInst,
466
+ nativeEvent,
467
+ nativeEventTarget,
468
+ );
469
+
470
+ if (composition === null) {
471
+ return beforeInput;
472
+ }
473
+
474
+ if (beforeInput === null) {
475
+ return composition;
476
+ }
477
+
478
+ return [composition, beforeInput];
479
},
480
};
481
packages/react-dom/src/events/__tests__/BeforeInputEventPlugin-test.internal.js
+21
-48
@@ -76,7 +76,12 @@ describe('BeforeInputEventPlugin', function() {
76
return function() {
77
const newArgs = [node].concat(Array.prototype.slice.call(arguments));
78
const newEvents = extract.apply(this, newArgs);
79
- Array.prototype.push.apply(events, newEvents);
79
+
80
+ if (Array.isArray(newEvents)) {
81
+ Array.prototype.push.apply(events, newEvents);
82
+ } else if (newEvents) {
83
+ events.push(newEvents);
84
+ }
85
};
86
}
87
@@ -156,32 +161,17 @@ describe('BeforeInputEventPlugin', function() {
161
// keyUp.
162
const Expected_Webkit = () => [
163
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
159
- {type: null},
160
- {type: null},
164
{type: ModuleCache.SyntheticInputEvent, data: {data: 'A'}},
162
- {type: null},
163
- {type: null}, // textinput of A
164
- {type: null},
165
- {type: null}, // keyUp of 65
166
- {type: null},
165
+ // textinput of A
166
+ // keyUp of 65
167
{type: ModuleCache.SyntheticInputEvent, data: {data: 'abc'}},
168
- {type: null},
169
- {type: null}, // textinput of abc
170
- {type: null},
171
- {type: null}, // keyUp of 32
172
- {type: null},
168
+ // textinput of abc
169
+ // keyUp of 32
170
{type: ModuleCache.SyntheticInputEvent, data: {data: 'xyz'}},
174
- {type: null},
175
- {type: null}, // textinput of xyz
176
- {type: null},
177
- {type: null}, // keyUp of 32
171
+ // textinput of xyz
172
+ // keyUp of 32
173
{type: ModuleCache.SyntheticCompositionEvent, data: {data: 'Hello'}},
179
- {type: null},
180
-
174
// Emoji test
182
- {type: null},
183
- {type: null},
184
- {type: null},
175
{type: ModuleCache.SyntheticInputEvent, data: {data: '\uD83D\uDE0A'}},
176
];
177
@@ -191,39 +181,22 @@ describe('BeforeInputEventPlugin', function() {
181
// element, not event data.
182
const Expected_IE11 = () => [
183
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
194
- {type: null},
195
- {type: null},
196
- {type: null}, // textInput of A
197
- {type: null},
198
- {type: null}, // textinput of A
199
- {type: null},
200
- {type: null}, // keyUp of 65
201
- {type: null},
202
- {type: null}, // textInput of abc
203
- {type: null},
204
- {type: null}, // textinput of abc
205
-
184
+ // textInput of A
185
+ // textinput of A
186
+ // keyUp of 65
187
+ // textInput of abc
188
+ // textinput of abc
189
// fallbackData should NOT be set at keyUp with any of END_KEYCODES
207
- {type: null},
208
- {type: null}, // keyUp of 32
209
-
210
- {type: null},
211
- {type: null}, // textInput of xyz
212
- {type: null},
213
- {type: null}, // textinput of xyz
214
- {type: null},
215
- {type: null}, // keyUp of 32
216
-
190
+ // keyUp of 32
191
+ // textInput of xyz
192
+ // textinput of xyz
193
+ // keyUp of 32
194
// fallbackData is retrieved from the element, which is XYZ,
195
// at a time of compositionend
196
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
197
{type: ModuleCache.SyntheticInputEvent, data: {data: 'XYZ'}},
221
-
198
// Emoji test
223
- {type: null},
199
{type: ModuleCache.SyntheticInputEvent, data: {data: '\uD83D\uDE0A'}},
225
- {type: null},
226
- {type: null},
200
];
201
202
function TestEditableReactComponent(Emulator, Scenario, ExpectedResult) {