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 <itten@live.com>
This commit is contained in:
Sebastian Markbåge
2021-04-07 07:57:43 -07:00
committed by GitHub
co-authored by Behnam Mohammadi
parent ee6a05c2bf
commit 172e89b4bf
38 changed files with 141 additions and 97 deletions
@@ -145,6 +145,8 @@ export default {
componentScope = currentScope;
}
const isArray = Array.isArray;
// Next we'll define a few helpers that helps us
// tell if some values don't have to be declared as deps.
@@ -157,7 +159,7 @@ export default {
// ^^^ true for this reference
// False for everything else.
function isStableKnownHookValue(resolved) {
if (!Array.isArray(resolved.defs)) {
if (!isArray(resolved.defs)) {
return false;
}
const def = resolved.defs[0];
@@ -226,7 +228,7 @@ export default {
if (
id.type === 'ArrayPattern' &&
id.elements.length === 2 &&
Array.isArray(resolved.identifiers)
isArray(resolved.identifiers)
) {
// Is second tuple value the same reference we're checking?
if (id.elements[1] === resolved.identifiers[0]) {
@@ -253,10 +255,7 @@ export default {
}
}
} else if (name === 'useTransition') {
if (
id.type === 'ArrayPattern' &&
Array.isArray(resolved.identifiers)
) {
if (id.type === 'ArrayPattern' && isArray(resolved.identifiers)) {
// Is first tuple value the same reference we're checking?
if (id.elements[0] === resolved.identifiers[0]) {
// Setter is stable.
@@ -270,7 +269,7 @@ export default {
// Some are just functions that don't reference anything dynamic.
function isFunctionWithoutCapturedValues(resolved) {
if (!Array.isArray(resolved.defs)) {
if (!isArray(resolved.defs)) {
return false;
}
const def = resolved.defs[0];
+2 -1
View File
@@ -8,6 +8,7 @@
import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
function captureAssertion(fn) {
// Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
@@ -42,7 +43,7 @@ export function unstable_toMatchRenderedOutput(root, expectedJSX) {
let actualJSX;
if (actualJSON === null || typeof actualJSON === 'string') {
actualJSX = actualJSON;
} else if (Array.isArray(actualJSON)) {
} else if (isArray(actualJSON)) {
if (actualJSON.length === 0) {
actualJSX = null;
} else if (actualJSON.length === 1) {
+2 -1
View File
@@ -105,6 +105,7 @@ import type {
ElementType,
} from 'react-devtools-shared/src/types';
import is from 'shared/objectIs';
import isArray from 'shared/isArray';
type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
type getTypeSymbolType = (type: any) => Symbol | number;
@@ -1137,7 +1138,7 @@ export function attach(
memoizedState.hasOwnProperty('create') &&
memoizedState.hasOwnProperty('destroy') &&
memoizedState.hasOwnProperty('deps') &&
(memoizedState.deps === null || Array.isArray(memoizedState.deps)) &&
(memoizedState.deps === null || isArray(memoizedState.deps)) &&
memoizedState.hasOwnProperty('next')
);
}
+6 -5
View File
@@ -9,6 +9,7 @@
import {copy} from 'clipboard-js';
import {dehydrate} from '../hydration';
import isArray from 'shared/isArray';
import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types';
@@ -61,9 +62,9 @@ export function copyWithDelete(
index: number = 0,
): Object | Array<any> {
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === path.length) {
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((key: any): number), 1);
} else {
delete updated[key];
@@ -84,12 +85,12 @@ export function copyWithRename(
index: number = 0,
): Object | Array<any> {
const oldKey = oldPath[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === oldPath.length) {
const newKey = newPath[index];
// $FlowFixMe number or string is fine here
updated[newKey] = updated[oldKey];
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((oldKey: any): number), 1);
} else {
delete updated[oldKey];
@@ -111,7 +112,7 @@ export function copyWithSet(
return value;
}
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
// $FlowFixMe number or string is fine here
updated[key] = copyWithSet(obj[key], path, value, index + 1);
return updated;
+4 -3
View File
@@ -12,6 +12,7 @@ import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCur
import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import {getToStringValue, toString} from './ToStringValue';
import isArray from 'shared/isArray';
let didWarnValueDefaultValue;
@@ -45,15 +46,15 @@ function checkSelectPropTypes(props) {
if (props[propName] == null) {
continue;
}
const isArray = Array.isArray(props[propName]);
if (props.multiple && !isArray) {
const propNameIsArray = isArray(props[propName]);
if (props.multiple && !propNameIsArray) {
console.error(
'The `%s` prop supplied to <select> must be an array if ' +
'`multiple` is true.%s',
propName,
getDeclarationErrorAddendum(),
);
} else if (!props.multiple && isArray) {
} else if (!props.multiple && propNameIsArray) {
console.error(
'The `%s` prop supplied to <select> must be a scalar ' +
'value if `multiple` is false.%s',
+2 -2
View File
@@ -8,12 +8,12 @@
*/
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
import {getToStringValue, toString} from './ToStringValue';
import type {ToStringValue} from './ToStringValue';
import {disableTextareaChildren} from 'shared/ReactFeatureFlags';
let didWarnValDefaultVal = false;
@@ -100,7 +100,7 @@ export function initWrapperState(element: Element, props: Object) {
defaultValue == null,
'If you supply `defaultValue` on a <textarea>, do not pass children.',
);
if (Array.isArray(children)) {
if (isArray(children)) {
invariant(
children.length <= 1,
'<textarea> can only have at most one child.',
@@ -46,8 +46,7 @@ import hyphenateStyleName from '../shared/hyphenateStyleName';
import invariant from 'shared/invariant';
import hasOwnProperty from 'shared/hasOwnProperty';
import sanitizeURL from '../shared/sanitizeURL';
const isArray = Array.isArray;
import isArray from 'shared/isArray';
// Per response, global state that is not contextual to the rendering subtree.
export type ResponseState = {
+6 -5
View File
@@ -14,6 +14,7 @@ import type {ReactProvider, ReactContext} from 'shared/ReactTypes';
import * as React from 'react';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame';
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -1438,7 +1439,7 @@ class ReactDOMServerRenderer {
defaultValue == null,
'If you supply `defaultValue` on a <textarea>, do not pass children.',
);
if (Array.isArray(textareaChildren)) {
if (isArray(textareaChildren)) {
invariant(
textareaChildren.length <= 1,
'<textarea> can only have at most one child.',
@@ -1467,14 +1468,14 @@ class ReactDOMServerRenderer {
if (props[propName] == null) {
continue;
}
const isArray = Array.isArray(props[propName]);
if (props.multiple && !isArray) {
const propNameIsArray = isArray(props[propName]);
if (props.multiple && !propNameIsArray) {
console.error(
'The `%s` prop supplied to <select> must be an array if ' +
'`multiple` is true.',
propName,
);
} else if (!props.multiple && isArray) {
} else if (!props.multiple && propNameIsArray) {
console.error(
'The `%s` prop supplied to <select> must be a scalar ' +
'value if `multiple` is false.',
@@ -1515,7 +1516,7 @@ class ReactDOMServerRenderer {
value = optionChildren;
}
selected = false;
if (Array.isArray(selectValue)) {
if (isArray(selectValue)) {
// multiple
for (let j = 0; j < selectValue.length; j++) {
if ('' + selectValue[j] === value) {
+4 -3
View File
@@ -24,6 +24,7 @@ import {
rethrowCaughtError,
invokeGuardedCallbackAndCatchFirstError,
} from 'shared/ReactErrorUtils';
import isArray from 'shared/isArray';
// Keep in sync with ReactDOM.js, and ReactTestUtilsAct.js:
const EventInternals =
@@ -97,7 +98,7 @@ function validateClassInstance(inst, methodName) {
}
let received;
const stringified = '' + inst;
if (Array.isArray(inst)) {
if (isArray(inst)) {
received = 'an array';
} else if (inst && inst.nodeType === ELEMENT_NODE && inst.tagName) {
received = 'a DOM node';
@@ -197,7 +198,7 @@ function scryRenderedDOMComponentsWithClass(root, classNames) {
}
const classList = className.split(/\s+/);
if (!Array.isArray(classNames)) {
if (!isArray(classNames)) {
invariant(
classNames !== undefined,
'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
@@ -365,7 +366,7 @@ function executeDispatch(event, listener, inst) {
function executeDispatchesInOrder(event) {
const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances;
if (Array.isArray(dispatchListeners)) {
if (isArray(dispatchListeners)) {
for (let i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
@@ -12,6 +12,7 @@ import {
deepDiffer,
flattenStyle,
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
import isArray from 'shared/isArray';
import type {AttributeConfiguration} from './ReactNativeTypes';
@@ -51,7 +52,7 @@ function restoreDeletedValuesInNestedArray(
node: NestedNode,
validAttributes: AttributeConfiguration,
) {
if (Array.isArray(node)) {
if (isArray(node)) {
let i = node.length;
while (i-- && removedKeyCount > 0) {
restoreDeletedValuesInNestedArray(
@@ -163,12 +164,12 @@ function diffNestedProperty(
return updatePayload;
}
if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) {
if (!isArray(prevProp) && !isArray(nextProp)) {
// Both are leaves, we can diff the leaves.
return diffProperties(updatePayload, prevProp, nextProp, validAttributes);
}
if (Array.isArray(prevProp) && Array.isArray(nextProp)) {
if (isArray(prevProp) && isArray(nextProp)) {
// Both are arrays, we can diff the arrays.
return diffNestedArrayProperty(
updatePayload,
@@ -178,7 +179,7 @@ function diffNestedProperty(
);
}
if (Array.isArray(prevProp)) {
if (isArray(prevProp)) {
return diffProperties(
updatePayload,
// $FlowFixMe - We know that this is always an object when the input is.
@@ -212,7 +213,7 @@ function addNestedProperty(
return updatePayload;
}
if (!Array.isArray(nextProp)) {
if (!isArray(nextProp)) {
// Add each property of the leaf.
return addProperties(updatePayload, nextProp, validAttributes);
}
@@ -242,7 +243,7 @@ function clearNestedProperty(
return updatePayload;
}
if (!Array.isArray(prevProp)) {
if (!isArray(prevProp)) {
// Add each property of the leaf.
return clearProperties(updatePayload, prevProp, validAttributes);
}
@@ -7,6 +7,7 @@
import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
export let getFiberCurrentPropsFromNode = null;
export let getInstanceFromNode = null;
@@ -36,14 +37,14 @@ if (__DEV__) {
const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances;
const listenersIsArr = Array.isArray(dispatchListeners);
const listenersIsArr = isArray(dispatchListeners);
const listenersLen = listenersIsArr
? dispatchListeners.length
: dispatchListeners
? 1
: 0;
const instancesIsArr = Array.isArray(dispatchInstances);
const instancesIsArr = isArray(dispatchInstances);
const instancesLen = instancesIsArr
? dispatchInstances.length
: dispatchInstances
@@ -78,7 +79,7 @@ export function executeDispatchesInOrder(event) {
if (__DEV__) {
validateEventDispatches(event);
}
if (Array.isArray(dispatchListeners)) {
if (isArray(dispatchListeners)) {
for (let i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
@@ -106,7 +107,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) {
if (__DEV__) {
validateEventDispatches(event);
}
if (Array.isArray(dispatchListeners)) {
if (isArray(dispatchListeners)) {
for (let i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
@@ -150,7 +151,7 @@ export function executeDirectDispatch(event) {
const dispatchListener = event._dispatchListeners;
const dispatchInstance = event._dispatchInstances;
invariant(
!Array.isArray(dispatchListener),
!isArray(dispatchListener),
'executeDirectDispatch(...): Invalid `event`.',
);
event.currentTarget = dispatchListener
@@ -8,6 +8,7 @@
*/
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
/**
* Accumulates items that must not be null or undefined.
@@ -31,11 +32,11 @@ function accumulate<T>(
// Both are not empty. Warning: Never call x.concat(y) when you are not
// certain that x is an Array (x could be a string with concat method).
if (Array.isArray(current)) {
if (isArray(current)) {
return current.concat(next);
}
if (Array.isArray(next)) {
if (isArray(next)) {
return [current].concat(next);
}
@@ -8,6 +8,7 @@
*/
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
/**
* Accumulates items that must not be null or undefined into the first one. This
@@ -37,8 +38,8 @@ function accumulateInto<T>(
// Both are not empty. Warning: Never call x.concat(y) when you are not
// certain that x is an Array (x could be a string with concat method).
if (Array.isArray(current)) {
if (Array.isArray(next)) {
if (isArray(current)) {
if (isArray(next)) {
current.push.apply(current, next);
return current;
}
@@ -46,7 +47,7 @@ function accumulateInto<T>(
return current;
}
if (Array.isArray(next)) {
if (isArray(next)) {
// A bit too dangerous to mutate `next`.
return [current].concat(next);
}
+5 -4
View File
@@ -21,6 +21,7 @@ import type {RootTag} from 'react-reconciler/src/ReactRootTags';
import * as Scheduler from 'scheduler/unstable_mock';
import {REACT_FRAGMENT_TYPE, REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
import isArray from 'shared/isArray';
import {
DefaultEventPriority,
IdleEventPriority,
@@ -604,7 +605,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
if (typeof child === 'string') {
return child;
}
if (Array.isArray(child)) {
if (isArray(child)) {
if (child.length === 0) {
return null;
}
@@ -618,7 +619,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
}
return children;
}
if (Array.isArray(child.children)) {
if (isArray(child.children)) {
// This is an instance.
const instance: Instance = (child: any);
const children = childToJSX(instance.children, instance.text);
@@ -668,7 +669,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
if (children === null) {
return null;
}
if (Array.isArray(children)) {
if (isArray(children)) {
return {
$$typeof: REACT_ELEMENT_TYPE,
type: REACT_FRAGMENT_TYPE,
@@ -687,7 +688,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
if (children === null) {
return null;
}
if (Array.isArray(children)) {
if (isArray(children)) {
return {
$$typeof: REACT_ELEMENT_TYPE,
type: REACT_FRAGMENT_TYPE,
@@ -31,6 +31,7 @@ import {
SimpleMemoComponent,
} from './ReactWorkTags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {
warnAboutStringRefs,
enableLazyElements,
@@ -97,8 +98,6 @@ if (__DEV__) {
};
}
const isArray = Array.isArray;
function coerceRef(
returnFiber: Fiber,
current: Fiber | null,
@@ -31,6 +31,7 @@ import {
SimpleMemoComponent,
} from './ReactWorkTags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {
warnAboutStringRefs,
enableLazyElements,
@@ -97,8 +98,6 @@ if (__DEV__) {
};
}
const isArray = Array.isArray;
function coerceRef(
returnFiber: Fiber,
current: Fiber | null,
@@ -87,6 +87,7 @@ import {
enableSuspenseLayoutEffectSemantics,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import shallowEqual from 'shared/shallowEqual';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import getComponentNameFromType from 'shared/getComponentNameFromType';
@@ -2713,11 +2714,11 @@ function validateTailOptions(
function validateSuspenseListNestedChild(childSlot: mixed, index: number) {
if (__DEV__) {
const isArray = Array.isArray(childSlot);
const isAnArray = isArray(childSlot);
const isIterable =
!isArray && typeof getIteratorFn(childSlot) === 'function';
if (isArray || isIterable) {
const type = isArray ? 'array' : 'iterable';
!isAnArray && typeof getIteratorFn(childSlot) === 'function';
if (isAnArray || isIterable) {
const type = isAnArray ? 'array' : 'iterable';
console.error(
'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' +
'an additional SuspenseList to configure its revealOrder: ' +
@@ -2745,7 +2746,7 @@ function validateSuspenseListChildren(
children !== null &&
children !== false
) {
if (Array.isArray(children)) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
if (!validateSuspenseListNestedChild(children[i], i)) {
return;
@@ -87,6 +87,7 @@ import {
enableSuspenseLayoutEffectSemantics,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import shallowEqual from 'shared/shallowEqual';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import getComponentNameFromType from 'shared/getComponentNameFromType';
@@ -2713,11 +2714,11 @@ function validateTailOptions(
function validateSuspenseListNestedChild(childSlot: mixed, index: number) {
if (__DEV__) {
const isArray = Array.isArray(childSlot);
const isAnArray = isArray(childSlot);
const isIterable =
!isArray && typeof getIteratorFn(childSlot) === 'function';
if (isArray || isIterable) {
const type = isArray ? 'array' : 'iterable';
!isAnArray && typeof getIteratorFn(childSlot) === 'function';
if (isAnArray || isIterable) {
const type = isAnArray ? 'array' : 'iterable';
console.error(
'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' +
'an additional SuspenseList to configure its revealOrder: ' +
@@ -2745,7 +2746,7 @@ function validateSuspenseListChildren(
children !== null &&
children !== false
) {
if (Array.isArray(children)) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
if (!validateSuspenseListNestedChild(children[i], i)) {
return;
@@ -36,6 +36,7 @@ import shallowEqual from 'shared/shallowEqual';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
@@ -81,7 +82,6 @@ import {
} from './SchedulingProfiler';
const fakeInternalInstance = {};
const isArray = Array.isArray;
// React.Component uses a shared frozen object by default.
// We'll use it to determine whether we need to initialize legacy refs.
@@ -36,6 +36,7 @@ import shallowEqual from 'shared/shallowEqual';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
@@ -81,7 +82,6 @@ import {
} from './SchedulingProfiler';
const fakeInternalInstance = {};
const isArray = Array.isArray;
// React.Component uses a shared frozen object by default.
// We'll use it to determine whether we need to initialize legacy refs.
@@ -87,6 +87,7 @@ import {
import invariant from 'shared/invariant';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import is from 'shared/objectIs';
import isArray from 'shared/isArray';
import {
markWorkInProgressReceivedUpdate,
checkIfWorkInProgressReceivedUpdate,
@@ -229,7 +230,7 @@ function updateHookTypesDev() {
function checkDepsAreArrayDev(deps: mixed) {
if (__DEV__) {
if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
if (deps !== undefined && deps !== null && !isArray(deps)) {
// Verify deps, but only on mount to avoid extra checks.
// It's unlikely their type would change as usually you define them inline.
console.error(
@@ -87,6 +87,7 @@ import {
import invariant from 'shared/invariant';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import is from 'shared/objectIs';
import isArray from 'shared/isArray';
import {
markWorkInProgressReceivedUpdate,
checkIfWorkInProgressReceivedUpdate,
@@ -229,7 +230,7 @@ function updateHookTypesDev() {
function checkDepsAreArrayDev(deps: mixed) {
if (__DEV__) {
if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
if (deps !== undefined && deps !== null && !isArray(deps)) {
// Verify deps, but only on mount to avoid extra checks.
// It's unlikely their type would change as usually you define them inline.
console.error(
@@ -34,6 +34,7 @@ import {
} from './ReactWorkTags';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {getPublicInstance} from './ReactFiberHostConfig';
@@ -482,9 +483,9 @@ if (__DEV__) {
index: number,
) => {
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === path.length) {
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((key: any): number), 1);
} else {
delete updated[key];
@@ -510,12 +511,12 @@ if (__DEV__) {
index: number,
) => {
const oldKey = oldPath[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === oldPath.length) {
const newKey = newPath[index];
// $FlowFixMe number or string is fine here
updated[newKey] = updated[oldKey];
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((oldKey: any): number), 1);
} else {
delete updated[oldKey];
@@ -564,7 +565,7 @@ if (__DEV__) {
return value;
}
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
// $FlowFixMe number or string is fine here
updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
return updated;
@@ -34,6 +34,7 @@ import {
} from './ReactWorkTags';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {getPublicInstance} from './ReactFiberHostConfig';
@@ -482,9 +483,9 @@ if (__DEV__) {
index: number,
) => {
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === path.length) {
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((key: any): number), 1);
} else {
delete updated[key];
@@ -510,12 +511,12 @@ if (__DEV__) {
index: number,
) => {
const oldKey = oldPath[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
if (index + 1 === oldPath.length) {
const newKey = newPath[index];
// $FlowFixMe number or string is fine here
updated[newKey] = updated[oldKey];
if (Array.isArray(updated)) {
if (isArray(updated)) {
updated.splice(((oldKey: any): number), 1);
} else {
delete updated[oldKey];
@@ -564,7 +565,7 @@ if (__DEV__) {
return value;
}
const key = path[index];
const updated = Array.isArray(obj) ? obj.slice() : {...obj};
const updated = isArray(obj) ? obj.slice() : {...obj};
// $FlowFixMe number or string is fine here
updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
return updated;
@@ -24,6 +24,8 @@ export {
requireModule,
} from 'ReactFlightDOMRelayClientIntegration';
import isArray from 'shared/isArray';
export type {ModuleMetaData} from 'ReactFlightDOMRelayClientIntegration';
export type UninitializedModel = JSONValue;
@@ -35,7 +37,7 @@ function parseModelRecursively(response: Response, parentObj, value) {
return parseModelString(response, parentObj, value);
}
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
if (isArray(value)) {
const parsedValue = [];
for (let i = 0; i < value.length; i++) {
(parsedValue: any)[i] = parseModelRecursively(
@@ -14,6 +14,7 @@ import type {Request, ReactModel} from 'react-server/src/ReactFlightServer';
import JSResourceReference from 'JSResourceReference';
import hasOwnProperty from 'shared/hasOwnProperty';
import isArray from 'shared/isArray';
export type ModuleReference<T> = JSResourceReference<T>;
@@ -82,7 +83,7 @@ function convertModelToJSON(
): JSONValue {
const json = resolveModelToJSON(request, parent, key, model);
if (typeof json === 'object' && json !== null) {
if (Array.isArray(json)) {
if (isArray(json)) {
const jsonArray: Array<JSONValue> = [];
for (let i = 0; i < json.length; i++) {
jsonArray[i] = convertModelToJSON(request, json, '' + i, json[i]);
@@ -17,6 +17,8 @@ import NullDependency from 'webpack/lib/dependencies/NullDependency';
import AsyncDependenciesBlock from 'webpack/lib/AsyncDependenciesBlock';
import Template from 'webpack/lib/Template';
import isArray from 'shared/isArray';
class ClientReferenceDependency extends ModuleDependency {
constructor(request) {
super(request);
@@ -76,7 +78,7 @@ export default class ReactFlightWebpackPlugin {
];
} else if (
typeof options.clientReferences === 'string' ||
!Array.isArray(options.clientReferences)
!isArray(options.clientReferences)
) {
this.clientReferences = [(options.clientReferences: $FlowFixMe)];
} else {
@@ -24,6 +24,8 @@ export {
requireModule,
} from 'ReactFlightNativeRelayClientIntegration';
import isArray from 'shared/isArray';
export type {ModuleMetaData} from 'ReactFlightNativeRelayClientIntegration';
export type UninitializedModel = JSONValue;
@@ -35,7 +37,7 @@ function parseModelRecursively(response: Response, parentObj, value) {
return parseModelString(response, parentObj, value);
}
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
if (isArray(value)) {
const parsedValue = [];
for (let i = 0; i < value.length; i++) {
(parsedValue: any)[i] = parseModelRecursively(
@@ -8,9 +8,9 @@
*/
import type {RowEncoding, JSONValue} from './ReactFlightNativeRelayProtocol';
import type {Request, ReactModel} from 'react-server/src/ReactFlightServer';
import hasOwnProperty from 'shared/hasOwnProperty';
import isArray from 'shared/isArray';
import JSResourceReferenceImpl from 'JSResourceReferenceImpl';
export type ModuleReference<T> = JSResourceReferenceImpl<T>;
@@ -80,7 +80,7 @@ function convertModelToJSON(
): JSONValue {
const json = resolveModelToJSON(request, parent, key, model);
if (typeof json === 'object' && json !== null) {
if (Array.isArray(json)) {
if (isArray(json)) {
const jsonArray: Array<JSONValue> = [];
for (let i = 0; i < json.length; i++) {
jsonArray[i] = convertModelToJSON(request, json, '' + i, json[i]);
+2 -1
View File
@@ -51,6 +51,7 @@ import {REACT_ELEMENT_TYPE, REACT_SUSPENSE_TYPE} from 'shared/ReactSymbols';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
const ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
@@ -287,7 +288,7 @@ function renderNode(request: Request, task: Task, node: ReactNodeList): void {
return;
}
if (Array.isArray(node)) {
if (isArray(node)) {
if (node.length > 0) {
for (let i = 0; i < node.length; i++) {
renderNode(request, task, node[i]);
+1 -2
View File
@@ -44,8 +44,7 @@ import {
import ReactSharedInternals from 'shared/ReactSharedInternals';
import invariant from 'shared/invariant';
const isArray = Array.isArray;
import isArray from 'shared/isArray';
type ReactJSONValue =
| string
+2 -1
View File
@@ -8,6 +8,7 @@
*/
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
import isArray from 'shared/isArray';
import {DefaultEventPriority} from 'react-reconciler/src/ReactEventPriorities';
export type Type = string;
@@ -84,7 +85,7 @@ export function appendChild(
child: Instance | TextInstance,
): void {
if (__DEV__) {
if (!Array.isArray(parentInstance.children)) {
if (!isArray(parentInstance.children)) {
console.error(
'An invalid container has been provided. ' +
'This may indicate that another renderer is being used in addition to the test renderer. ' +
+2 -1
View File
@@ -43,6 +43,7 @@ import {
ScopeComponent,
} from 'react-reconciler/src/ReactWorkTags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import getComponentNameFromType from 'shared/getComponentNameFromType';
import ReactVersion from 'shared/ReactVersion';
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -158,7 +159,7 @@ function flatten(arr) {
while (n.i < n.array.length) {
const el = n.array[n.i];
n.i += 1;
if (Array.isArray(el)) {
if (isArray(el)) {
stack.push(n);
stack.push({i: 0, array: el});
break;
+3 -2
View File
@@ -10,6 +10,7 @@
import type {ReactNodeList} from 'shared/ReactTypes';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
import {
getIteratorFn,
REACT_ELEMENT_TYPE,
@@ -110,7 +111,7 @@ function mapIntoArray(
// so that it's consistent if the number of children grows:
const childKey =
nameSoFar === '' ? SEPARATOR + getElementKey(child, 0) : nameSoFar;
if (Array.isArray(mappedChild)) {
if (isArray(mappedChild)) {
let escapedChildKey = '';
if (childKey != null) {
escapedChildKey = escapeUserProvidedKey(childKey) + '/';
@@ -142,7 +143,7 @@ function mapIntoArray(
const nextNamePrefix =
nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
if (Array.isArray(children)) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
child = children[i];
nextName = nextNamePrefix + getElementKey(child, i);
+5 -4
View File
@@ -23,6 +23,7 @@ import {
} from 'shared/ReactSymbols';
import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
import checkPropTypes from 'shared/checkPropTypes';
import isArray from 'shared/isArray';
import ReactCurrentOwner from './ReactCurrentOwner';
import {
@@ -168,7 +169,7 @@ function validateChildKeys(node, parentType) {
if (typeof node !== 'object') {
return;
}
if (Array.isArray(node)) {
if (isArray(node)) {
for (let i = 0; i < node.length; i++) {
const child = node[i];
if (isValidElement(child)) {
@@ -313,7 +314,7 @@ export function jsxWithValidation(
let typeString;
if (type === null) {
typeString = 'null';
} else if (Array.isArray(type)) {
} else if (isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = `<${getComponentNameFromType(type.type) || 'Unknown'} />`;
@@ -352,7 +353,7 @@ export function jsxWithValidation(
const children = props.children;
if (children !== undefined) {
if (isStaticChildren) {
if (Array.isArray(children)) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
validateChildKeys(children[i], type);
}
@@ -437,7 +438,7 @@ export function createElementWithValidation(type, props, children) {
let typeString;
if (type === null) {
typeString = 'null';
} else if (Array.isArray(type)) {
} else if (isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = `<${getComponentNameFromType(type.type) || 'Unknown'} />`;
@@ -23,6 +23,7 @@ import {
} from 'shared/ReactSymbols';
import {warnAboutSpreadingKeyToJSX} from 'shared/ReactFeatureFlags';
import hasOwnProperty from 'shared/hasOwnProperty';
import isArray from 'shared/isArray';
import {jsxDEV} from './ReactJSXElement';
import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame';
@@ -182,7 +183,7 @@ function validateChildKeys(node, parentType) {
if (typeof node !== 'object') {
return;
}
if (Array.isArray(node)) {
if (isArray(node)) {
for (let i = 0; i < node.length; i++) {
const child = node[i];
if (isValidElement(child)) {
@@ -329,7 +330,7 @@ export function jsxWithValidation(
let typeString;
if (type === null) {
typeString = 'null';
} else if (Array.isArray(type)) {
} else if (isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = `<${getComponentNameFromType(type.type) || 'Unknown'} />`;
@@ -366,7 +367,7 @@ export function jsxWithValidation(
const children = props.children;
if (children !== undefined) {
if (isStaticChildren) {
if (Array.isArray(children)) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
validateChildKeys(children[i], type);
}
+19
View File
@@ -0,0 +1,19 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
declare function isArray(a: mixed): boolean %checks(Array.isArray(a));
const isArrayImpl = Array.isArray;
// eslint-disable-next-line no-redeclare
function isArray(a: mixed): boolean {
return isArrayImpl(a);
}
export default isArray;