From 972ad957a53166a1d02bd21946fa095ab80aca23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Wed, 7 Apr 2021 10:57:43 -0400 Subject: [PATCH] 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 --- .../src/ExhaustiveDeps.js | 13 ++++++------- packages/jest-react/src/JestReact.js | 3 ++- .../src/backend/renderer.js | 3 ++- .../src/backend/utils.js | 11 ++++++----- .../react-dom/src/client/ReactDOMSelect.js | 7 ++++--- .../react-dom/src/client/ReactDOMTextarea.js | 4 ++-- .../src/server/ReactDOMServerFormatConfig.js | 3 +-- .../src/server/ReactPartialRenderer.js | 11 ++++++----- .../src/test-utils/ReactTestUtils.js | 7 ++++--- .../src/ReactNativeAttributePayload.js | 13 +++++++------ ...ctNativeAttributePayload-test.internal.js} | 0 .../src/legacy-events/EventPluginUtils.js | 11 ++++++----- .../src/legacy-events/accumulate.js | 5 +++-- .../src/legacy-events/accumulateInto.js | 7 ++++--- .../src/createReactNoop.js | 9 +++++---- .../src/ReactChildFiber.new.js | 3 +-- .../src/ReactChildFiber.old.js | 3 +-- .../src/ReactFiberBeginWork.new.js | 11 ++++++----- .../src/ReactFiberBeginWork.old.js | 11 ++++++----- .../src/ReactFiberClassComponent.new.js | 2 +- .../src/ReactFiberClassComponent.old.js | 2 +- .../src/ReactFiberHooks.new.js | 3 ++- .../src/ReactFiberHooks.old.js | 3 ++- .../src/ReactFiberReconciler.new.js | 11 ++++++----- .../src/ReactFiberReconciler.old.js | 11 ++++++----- .../ReactFlightDOMRelayClientHostConfig.js | 4 +++- .../ReactFlightDOMRelayServerHostConfig.js | 3 ++- .../src/ReactFlightWebpackPlugin.js | 4 +++- .../ReactFlightNativeRelayClientHostConfig.js | 4 +++- .../ReactFlightNativeRelayServerHostConfig.js | 4 ++-- packages/react-server/src/ReactFizzServer.js | 3 ++- .../react-server/src/ReactFlightServer.js | 3 +-- .../src/ReactTestHostConfig.js | 3 ++- .../src/ReactTestRenderer.js | 3 ++- packages/react/src/ReactChildren.js | 5 +++-- packages/react/src/ReactElementValidator.js | 9 +++++---- .../react/src/jsx/ReactJSXElementValidator.js | 7 ++++--- packages/shared/isArray.js | 19 +++++++++++++++++++ 38 files changed, 141 insertions(+), 97 deletions(-) rename packages/react-native-renderer/src/__tests__/{ReactNativeAttributePayload-test.js => ReactNativeAttributePayload-test.internal.js} (100%) create mode 100644 packages/shared/isArray.js diff --git a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js index 2c76ca5991f76..f4c36fcf2202d 100644 --- a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js +++ b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js @@ -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]; diff --git a/packages/jest-react/src/JestReact.js b/packages/jest-react/src/JestReact.js index 57790797b966d..1f26cbee3a328 100644 --- a/packages/jest-react/src/JestReact.js +++ b/packages/jest-react/src/JestReact.js @@ -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) { diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index 050a4e709ab32..c61edb45daa65 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -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') ); } diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index 7a4ff6295ab99..593459d78f646 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -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 { 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 { 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; diff --git a/packages/react-dom/src/client/ReactDOMSelect.js b/packages/react-dom/src/client/ReactDOMSelect.js index 1efca61905b4a..df336d4b92254 100644 --- a/packages/react-dom/src/client/ReactDOMSelect.js +++ b/packages/react-dom/src/client/ReactDOMSelect.js @@ -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 must be a scalar ' + 'value if `multiple` is false.%s', diff --git a/packages/react-dom/src/client/ReactDOMTextarea.js b/packages/react-dom/src/client/ReactDOMTextarea.js index 24fb591fcd8af..6e8aed5cc43cd 100644 --- a/packages/react-dom/src/client/ReactDOMTextarea.js +++ b/packages/react-dom/src/client/ReactDOMTextarea.js @@ -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