Skip to content

Commit 172e89b

Browse files
Reland Remove redundant initial of isArray (#21188)
* Remove redundant initial of isArray (#21163) * Reapply prettier * Type the isArray function with refinement support This ensures that an argument gets refined just like it does if isArray is used directly. I'm not sure how to express with just a direct reference so I added a function wrapper and confirmed that this does get inlined properly by closure compiler. * A few more * Rename unit test to internal This is not testing a bundle. Co-authored-by: Behnam Mohammadi <[email protected]>
1 parent ee6a05c commit 172e89b

38 files changed

+141
-97
lines changed

packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ export default {
145145
componentScope = currentScope;
146146
}
147147

148+
const isArray = Array.isArray;
149+
148150
// Next we'll define a few helpers that helps us
149151
// tell if some values don't have to be declared as deps.
150152

@@ -157,7 +159,7 @@ export default {
157159
// ^^^ true for this reference
158160
// False for everything else.
159161
function isStableKnownHookValue(resolved) {
160-
if (!Array.isArray(resolved.defs)) {
162+
if (!isArray(resolved.defs)) {
161163
return false;
162164
}
163165
const def = resolved.defs[0];
@@ -226,7 +228,7 @@ export default {
226228
if (
227229
id.type === 'ArrayPattern' &&
228230
id.elements.length === 2 &&
229-
Array.isArray(resolved.identifiers)
231+
isArray(resolved.identifiers)
230232
) {
231233
// Is second tuple value the same reference we're checking?
232234
if (id.elements[1] === resolved.identifiers[0]) {
@@ -253,10 +255,7 @@ export default {
253255
}
254256
}
255257
} else if (name === 'useTransition') {
256-
if (
257-
id.type === 'ArrayPattern' &&
258-
Array.isArray(resolved.identifiers)
259-
) {
258+
if (id.type === 'ArrayPattern' && isArray(resolved.identifiers)) {
260259
// Is first tuple value the same reference we're checking?
261260
if (id.elements[0] === resolved.identifiers[0]) {
262261
// Setter is stable.
@@ -270,7 +269,7 @@ export default {
270269

271270
// Some are just functions that don't reference anything dynamic.
272271
function isFunctionWithoutCapturedValues(resolved) {
273-
if (!Array.isArray(resolved.defs)) {
272+
if (!isArray(resolved.defs)) {
274273
return false;
275274
}
276275
const def = resolved.defs[0];

packages/jest-react/src/JestReact.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols';
99

1010
import invariant from 'shared/invariant';
11+
import isArray from 'shared/isArray';
1112

1213
function captureAssertion(fn) {
1314
// Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
@@ -42,7 +43,7 @@ export function unstable_toMatchRenderedOutput(root, expectedJSX) {
4243
let actualJSX;
4344
if (actualJSON === null || typeof actualJSON === 'string') {
4445
actualJSX = actualJSON;
45-
} else if (Array.isArray(actualJSON)) {
46+
} else if (isArray(actualJSON)) {
4647
if (actualJSON.length === 0) {
4748
actualJSX = null;
4849
} else if (actualJSON.length === 1) {

packages/react-devtools-shared/src/backend/renderer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ import type {
105105
ElementType,
106106
} from 'react-devtools-shared/src/types';
107107
import is from 'shared/objectIs';
108+
import isArray from 'shared/isArray';
108109

109110
type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
110111
type getTypeSymbolType = (type: any) => Symbol | number;
@@ -1137,7 +1138,7 @@ export function attach(
11371138
memoizedState.hasOwnProperty('create') &&
11381139
memoizedState.hasOwnProperty('destroy') &&
11391140
memoizedState.hasOwnProperty('deps') &&
1140-
(memoizedState.deps === null || Array.isArray(memoizedState.deps)) &&
1141+
(memoizedState.deps === null || isArray(memoizedState.deps)) &&
11411142
memoizedState.hasOwnProperty('next')
11421143
);
11431144
}

packages/react-devtools-shared/src/backend/utils.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import {copy} from 'clipboard-js';
1111
import {dehydrate} from '../hydration';
12+
import isArray from 'shared/isArray';
1213

1314
import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types';
1415

@@ -61,9 +62,9 @@ export function copyWithDelete(
6162
index: number = 0,
6263
): Object | Array<any> {
6364
const key = path[index];
64-
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
65+
const updated = isArray(obj) ? obj.slice() : {...obj};
6566
if (index + 1 === path.length) {
66-
if (Array.isArray(updated)) {
67+
if (isArray(updated)) {
6768
updated.splice(((key: any): number), 1);
6869
} else {
6970
delete updated[key];
@@ -84,12 +85,12 @@ export function copyWithRename(
8485
index: number = 0,
8586
): Object | Array<any> {
8687
const oldKey = oldPath[index];
87-
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
88+
const updated = isArray(obj) ? obj.slice() : {...obj};
8889
if (index + 1 === oldPath.length) {
8990
const newKey = newPath[index];
9091
// $FlowFixMe number or string is fine here
9192
updated[newKey] = updated[oldKey];
92-
if (Array.isArray(updated)) {
93+
if (isArray(updated)) {
9394
updated.splice(((oldKey: any): number), 1);
9495
} else {
9596
delete updated[oldKey];
@@ -111,7 +112,7 @@ export function copyWithSet(
111112
return value;
112113
}
113114
const key = path[index];
114-
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
115+
const updated = isArray(obj) ? obj.slice() : {...obj};
115116
// $FlowFixMe number or string is fine here
116117
updated[key] = copyWithSet(obj[key], path, value, index + 1);
117118
return updated;

packages/react-dom/src/client/ReactDOMSelect.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCur
1212

1313
import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
1414
import {getToStringValue, toString} from './ToStringValue';
15+
import isArray from 'shared/isArray';
1516

1617
let didWarnValueDefaultValue;
1718

@@ -45,15 +46,15 @@ function checkSelectPropTypes(props) {
4546
if (props[propName] == null) {
4647
continue;
4748
}
48-
const isArray = Array.isArray(props[propName]);
49-
if (props.multiple && !isArray) {
49+
const propNameIsArray = isArray(props[propName]);
50+
if (props.multiple && !propNameIsArray) {
5051
console.error(
5152
'The `%s` prop supplied to <select> must be an array if ' +
5253
'`multiple` is true.%s',
5354
propName,
5455
getDeclarationErrorAddendum(),
5556
);
56-
} else if (!props.multiple && isArray) {
57+
} else if (!props.multiple && propNameIsArray) {
5758
console.error(
5859
'The `%s` prop supplied to <select> must be a scalar ' +
5960
'value if `multiple` is false.%s',

packages/react-dom/src/client/ReactDOMTextarea.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
*/
99

1010
import invariant from 'shared/invariant';
11+
import isArray from 'shared/isArray';
1112

1213
import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
1314
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
1415
import {getToStringValue, toString} from './ToStringValue';
1516
import type {ToStringValue} from './ToStringValue';
16-
1717
import {disableTextareaChildren} from 'shared/ReactFeatureFlags';
1818

1919
let didWarnValDefaultVal = false;
@@ -100,7 +100,7 @@ export function initWrapperState(element: Element, props: Object) {
100100
defaultValue == null,
101101
'If you supply `defaultValue` on a <textarea>, do not pass children.',
102102
);
103-
if (Array.isArray(children)) {
103+
if (isArray(children)) {
104104
invariant(
105105
children.length <= 1,
106106
'<textarea> can only have at most one child.',

packages/react-dom/src/server/ReactDOMServerFormatConfig.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ import hyphenateStyleName from '../shared/hyphenateStyleName';
4646
import invariant from 'shared/invariant';
4747
import hasOwnProperty from 'shared/hasOwnProperty';
4848
import sanitizeURL from '../shared/sanitizeURL';
49-
50-
const isArray = Array.isArray;
49+
import isArray from 'shared/isArray';
5150

5251
// Per response, global state that is not contextual to the rendering subtree.
5352
export type ResponseState = {

packages/react-dom/src/server/ReactPartialRenderer.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {ReactProvider, ReactContext} from 'shared/ReactTypes';
1414

1515
import * as React from 'react';
1616
import invariant from 'shared/invariant';
17+
import isArray from 'shared/isArray';
1718
import getComponentNameFromType from 'shared/getComponentNameFromType';
1819
import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame';
1920
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -1438,7 +1439,7 @@ class ReactDOMServerRenderer {
14381439
defaultValue == null,
14391440
'If you supply `defaultValue` on a <textarea>, do not pass children.',
14401441
);
1441-
if (Array.isArray(textareaChildren)) {
1442+
if (isArray(textareaChildren)) {
14421443
invariant(
14431444
textareaChildren.length <= 1,
14441445
'<textarea> can only have at most one child.',
@@ -1467,14 +1468,14 @@ class ReactDOMServerRenderer {
14671468
if (props[propName] == null) {
14681469
continue;
14691470
}
1470-
const isArray = Array.isArray(props[propName]);
1471-
if (props.multiple && !isArray) {
1471+
const propNameIsArray = isArray(props[propName]);
1472+
if (props.multiple && !propNameIsArray) {
14721473
console.error(
14731474
'The `%s` prop supplied to <select> must be an array if ' +
14741475
'`multiple` is true.',
14751476
propName,
14761477
);
1477-
} else if (!props.multiple && isArray) {
1478+
} else if (!props.multiple && propNameIsArray) {
14781479
console.error(
14791480
'The `%s` prop supplied to <select> must be a scalar ' +
14801481
'value if `multiple` is false.',
@@ -1515,7 +1516,7 @@ class ReactDOMServerRenderer {
15151516
value = optionChildren;
15161517
}
15171518
selected = false;
1518-
if (Array.isArray(selectValue)) {
1519+
if (isArray(selectValue)) {
15191520
// multiple
15201521
for (let j = 0; j < selectValue.length; j++) {
15211522
if ('' + selectValue[j] === value) {

packages/react-dom/src/test-utils/ReactTestUtils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
rethrowCaughtError,
2525
invokeGuardedCallbackAndCatchFirstError,
2626
} from 'shared/ReactErrorUtils';
27+
import isArray from 'shared/isArray';
2728

2829
// Keep in sync with ReactDOM.js, and ReactTestUtilsAct.js:
2930
const EventInternals =
@@ -97,7 +98,7 @@ function validateClassInstance(inst, methodName) {
9798
}
9899
let received;
99100
const stringified = '' + inst;
100-
if (Array.isArray(inst)) {
101+
if (isArray(inst)) {
101102
received = 'an array';
102103
} else if (inst && inst.nodeType === ELEMENT_NODE && inst.tagName) {
103104
received = 'a DOM node';
@@ -197,7 +198,7 @@ function scryRenderedDOMComponentsWithClass(root, classNames) {
197198
}
198199
const classList = className.split(/\s+/);
199200

200-
if (!Array.isArray(classNames)) {
201+
if (!isArray(classNames)) {
201202
invariant(
202203
classNames !== undefined,
203204
'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
@@ -365,7 +366,7 @@ function executeDispatch(event, listener, inst) {
365366
function executeDispatchesInOrder(event) {
366367
const dispatchListeners = event._dispatchListeners;
367368
const dispatchInstances = event._dispatchInstances;
368-
if (Array.isArray(dispatchListeners)) {
369+
if (isArray(dispatchListeners)) {
369370
for (let i = 0; i < dispatchListeners.length; i++) {
370371
if (event.isPropagationStopped()) {
371372
break;

packages/react-native-renderer/src/ReactNativeAttributePayload.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
deepDiffer,
1313
flattenStyle,
1414
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
15+
import isArray from 'shared/isArray';
1516

1617
import type {AttributeConfiguration} from './ReactNativeTypes';
1718

@@ -51,7 +52,7 @@ function restoreDeletedValuesInNestedArray(
5152
node: NestedNode,
5253
validAttributes: AttributeConfiguration,
5354
) {
54-
if (Array.isArray(node)) {
55+
if (isArray(node)) {
5556
let i = node.length;
5657
while (i-- && removedKeyCount > 0) {
5758
restoreDeletedValuesInNestedArray(
@@ -163,12 +164,12 @@ function diffNestedProperty(
163164
return updatePayload;
164165
}
165166

166-
if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) {
167+
if (!isArray(prevProp) && !isArray(nextProp)) {
167168
// Both are leaves, we can diff the leaves.
168169
return diffProperties(updatePayload, prevProp, nextProp, validAttributes);
169170
}
170171

171-
if (Array.isArray(prevProp) && Array.isArray(nextProp)) {
172+
if (isArray(prevProp) && isArray(nextProp)) {
172173
// Both are arrays, we can diff the arrays.
173174
return diffNestedArrayProperty(
174175
updatePayload,
@@ -178,7 +179,7 @@ function diffNestedProperty(
178179
);
179180
}
180181

181-
if (Array.isArray(prevProp)) {
182+
if (isArray(prevProp)) {
182183
return diffProperties(
183184
updatePayload,
184185
// $FlowFixMe - We know that this is always an object when the input is.
@@ -212,7 +213,7 @@ function addNestedProperty(
212213
return updatePayload;
213214
}
214215

215-
if (!Array.isArray(nextProp)) {
216+
if (!isArray(nextProp)) {
216217
// Add each property of the leaf.
217218
return addProperties(updatePayload, nextProp, validAttributes);
218219
}
@@ -242,7 +243,7 @@ function clearNestedProperty(
242243
return updatePayload;
243244
}
244245

245-
if (!Array.isArray(prevProp)) {
246+
if (!isArray(prevProp)) {
246247
// Add each property of the leaf.
247248
return clearProperties(updatePayload, prevProp, validAttributes);
248249
}

packages/react-native-renderer/src/legacy-events/EventPluginUtils.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
99
import invariant from 'shared/invariant';
10+
import isArray from 'shared/isArray';
1011

1112
export let getFiberCurrentPropsFromNode = null;
1213
export let getInstanceFromNode = null;
@@ -36,14 +37,14 @@ if (__DEV__) {
3637
const dispatchListeners = event._dispatchListeners;
3738
const dispatchInstances = event._dispatchInstances;
3839

39-
const listenersIsArr = Array.isArray(dispatchListeners);
40+
const listenersIsArr = isArray(dispatchListeners);
4041
const listenersLen = listenersIsArr
4142
? dispatchListeners.length
4243
: dispatchListeners
4344
? 1
4445
: 0;
4546

46-
const instancesIsArr = Array.isArray(dispatchInstances);
47+
const instancesIsArr = isArray(dispatchInstances);
4748
const instancesLen = instancesIsArr
4849
? dispatchInstances.length
4950
: dispatchInstances
@@ -78,7 +79,7 @@ export function executeDispatchesInOrder(event) {
7879
if (__DEV__) {
7980
validateEventDispatches(event);
8081
}
81-
if (Array.isArray(dispatchListeners)) {
82+
if (isArray(dispatchListeners)) {
8283
for (let i = 0; i < dispatchListeners.length; i++) {
8384
if (event.isPropagationStopped()) {
8485
break;
@@ -106,7 +107,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) {
106107
if (__DEV__) {
107108
validateEventDispatches(event);
108109
}
109-
if (Array.isArray(dispatchListeners)) {
110+
if (isArray(dispatchListeners)) {
110111
for (let i = 0; i < dispatchListeners.length; i++) {
111112
if (event.isPropagationStopped()) {
112113
break;
@@ -150,7 +151,7 @@ export function executeDirectDispatch(event) {
150151
const dispatchListener = event._dispatchListeners;
151152
const dispatchInstance = event._dispatchInstances;
152153
invariant(
153-
!Array.isArray(dispatchListener),
154+
!isArray(dispatchListener),
154155
'executeDirectDispatch(...): Invalid `event`.',
155156
);
156157
event.currentTarget = dispatchListener

packages/react-native-renderer/src/legacy-events/accumulate.js

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

1010
import invariant from 'shared/invariant';
11+
import isArray from 'shared/isArray';
1112

1213
/**
1314
* Accumulates items that must not be null or undefined.
@@ -31,11 +32,11 @@ function accumulate<T>(
3132

3233
// Both are not empty. Warning: Never call x.concat(y) when you are not
3334
// certain that x is an Array (x could be a string with concat method).
34-
if (Array.isArray(current)) {
35+
if (isArray(current)) {
3536
return current.concat(next);
3637
}
3738

38-
if (Array.isArray(next)) {
39+
if (isArray(next)) {
3940
return [current].concat(next);
4041
}
4142

0 commit comments

Comments
 (0)