Skip to content

Commit

Permalink
Merge pull request #2085 from reduxjs/feature/9.0-react-is-inline
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Nov 16, 2023
2 parents 6ca2d66 + fdbd57c commit f1bf253
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 65 deletions.
10 changes: 3 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
"import": "./dist/react-redux.alternate-renderers.mjs"
}
},
"sideEffects": "false",
"sideEffects": false,
"files": [
"dist",
"es"
"dist"
],
"scripts": {
"build": "tsup",
Expand Down Expand Up @@ -72,7 +71,6 @@
},
"dependencies": {
"@types/use-sync-external-store": "^0.0.3",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"devDependencies": {
Expand All @@ -87,17 +85,15 @@
"@babel/preset-env": "^7.12.1",
"@babel/preset-typescript": "^7.14.5",
"@microsoft/api-extractor": "^7.18.1",
"@reduxjs/toolkit": "^2.0.0-beta.0",
"@reduxjs/toolkit": "^2.0.0-beta.4",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/jest-native": "^3.4.3",
"@testing-library/react": "13.0.0",
"@testing-library/react-12": "npm:@testing-library/react@^12",
"@testing-library/react-hooks": "^3.4.2",
"@testing-library/react-native": "^7.1.0",
"@types/object-assign": "^4.0.30",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-is": "^17",
"@types/react-native": "^0.67.4",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
Expand Down
45 changes: 27 additions & 18 deletions src/components/connect.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable valid-jsdoc, @typescript-eslint/no-unused-vars */
import type { ComponentType } from 'react'
import * as React from 'react'
import { isValidElementType, isContextConsumer } from 'react-is'
import { isValidElementType, isContextConsumer } from '../utils/react-is'

import type { Store } from 'redux'

Expand Down Expand Up @@ -491,15 +491,14 @@ function connect<
type WrappedComponentProps = TProps &
ConnectPropsMaybeWithoutContext<TProps>

if (
process.env.NODE_ENV !== 'production' &&
!isValidElementType(WrappedComponent)
) {
throw new Error(
`You must pass a component to the function returned by connect. Instead received ${stringifyComponent(
WrappedComponent
)}`
)
if (process.env.NODE_ENV !== 'production') {
const isValid = /*#__PURE__*/ isValidElementType(WrappedComponent)
if (!isValid)
throw new Error(
`You must pass a component to the function returned by connect. Instead received ${stringifyComponent(
WrappedComponent
)}`
)
}

const wrappedComponentName =
Expand Down Expand Up @@ -544,12 +543,22 @@ function connect<
const ContextToUse: ReactReduxContextInstance = React.useMemo(() => {
// Users may optionally pass in a custom context instance to use instead of our ReactReduxContext.
// Memoize the check that determines which context instance we should use.
return propsContext &&
propsContext.Consumer &&
// @ts-ignore
isContextConsumer(<propsContext.Consumer />)
? propsContext
: Context
let ResultContext = Context
if (propsContext?.Consumer) {
if (process.env.NODE_ENV !== 'production') {
const isValid = /*#__PURE__*/ isContextConsumer(
// @ts-ignore
<propsContext.Consumer />
)
if (!isValid) {
throw new Error(
'You must pass a valid React context consumer as `props.context`'
)
}
ResultContext = propsContext
}
}
return ResultContext
}, [propsContext, Context])

// Retrieve the store and ancestor subscription via context, if available
Expand Down Expand Up @@ -797,10 +806,10 @@ function connect<
const forwarded = _forwarded as ConnectedWrapperComponent
forwarded.displayName = displayName
forwarded.WrappedComponent = WrappedComponent
return hoistStatics(forwarded, WrappedComponent)
return /*#__PURE__*/ hoistStatics(forwarded, WrappedComponent)
}

return hoistStatics(Connect, WrappedComponent)
return /*#__PURE__*/ hoistStatics(Connect, WrappedComponent)
}

return wrapWithConnect
Expand Down
2 changes: 1 addition & 1 deletion src/utils/hoistStatics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
import type * as React from 'react'
import { ForwardRef, Memo, isMemo } from 'react-is'
import { ForwardRef, Memo, isMemo } from '../utils/react-is'

const REACT_STATICS = {
childContextTypes: true,
Expand Down
113 changes: 113 additions & 0 deletions src/utils/react-is.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import type { ElementType, MemoExoticComponent, ReactElement } from 'react'

// Directly ported from:
// https://unpkg.com/browse/[email protected]/cjs/react-is.production.js
// It's very possible this could change in the future, but given that
// we only use these in `connect`, this is a low priority.

const REACT_ELEMENT_TYPE = Symbol.for('react.element')
const REACT_PORTAL_TYPE = Symbol.for('react.portal')
const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment')
const REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode')
const REACT_PROFILER_TYPE = Symbol.for('react.profiler')
const REACT_PROVIDER_TYPE = Symbol.for('react.provider')
const REACT_CONTEXT_TYPE = Symbol.for('react.context')
const REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context')
const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref')
const REACT_SUSPENSE_TYPE = Symbol.for('react.suspense')
const REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list')
const REACT_MEMO_TYPE = Symbol.for('react.memo')
const REACT_LAZY_TYPE = Symbol.for('react.lazy')
const REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen')
const REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference')

export const ForwardRef = REACT_FORWARD_REF_TYPE
export const Memo = REACT_MEMO_TYPE

export function isValidElementType(type: any): type is ElementType {
if (typeof type === 'string' || typeof type === 'function') {
return true
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).

if (
type === REACT_FRAGMENT_TYPE ||
type === REACT_PROFILER_TYPE ||
type === REACT_STRICT_MODE_TYPE ||
type === REACT_SUSPENSE_TYPE ||
type === REACT_SUSPENSE_LIST_TYPE ||
type === REACT_OFFSCREEN_TYPE
) {
return true
}

if (typeof type === 'object' && type !== null) {
if (
type.$$typeof === REACT_LAZY_TYPE ||
type.$$typeof === REACT_MEMO_TYPE ||
type.$$typeof === REACT_PROVIDER_TYPE ||
type.$$typeof === REACT_CONTEXT_TYPE ||
type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object
// types supported by any Flight configuration anywhere since
// we don't know which Flight build this will end up being used
// with.
type.$$typeof === REACT_CLIENT_REFERENCE ||
type.getModuleId !== undefined
) {
return true
}
}

return false
}

function typeOf(object: any): symbol | undefined {
if (typeof object === 'object' && object !== null) {
const $$typeof = object.$$typeof

switch ($$typeof) {
case REACT_ELEMENT_TYPE: {
const type = object.type

switch (type) {
case REACT_FRAGMENT_TYPE:
case REACT_PROFILER_TYPE:
case REACT_STRICT_MODE_TYPE:
case REACT_SUSPENSE_TYPE:
case REACT_SUSPENSE_LIST_TYPE:
return type

default: {
const $$typeofType = type && type.$$typeof

switch ($$typeofType) {
case REACT_SERVER_CONTEXT_TYPE:
case REACT_CONTEXT_TYPE:
case REACT_FORWARD_REF_TYPE:
case REACT_LAZY_TYPE:
case REACT_MEMO_TYPE:
case REACT_PROVIDER_TYPE:
return $$typeofType

default:
return $$typeof
}
}
}
}

case REACT_PORTAL_TYPE: {
return $$typeof
}
}
}

return undefined
}

export function isContextConsumer(object: any): object is ReactElement {
return typeOf(object) === REACT_CONTEXT_TYPE
}

export function isMemo(object: any): object is MemoExoticComponent<any> {
return typeOf(object) === REACT_MEMO_TYPE
}
2 changes: 1 addition & 1 deletion test/typetests/react-redux-types.typetest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
fetchCount,
} from './counterApp'

import objectAssign from 'object-assign'
const objectAssign = Object.assign

class Counter extends Component<any, any> {
render() {
Expand Down
57 changes: 19 additions & 38 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2419,23 +2419,23 @@ __metadata:
languageName: node
linkType: hard

"@reduxjs/toolkit@npm:^2.0.0-beta.0":
version: 2.0.0-beta.0
resolution: "@reduxjs/toolkit@npm:2.0.0-beta.0"
"@reduxjs/toolkit@npm:^2.0.0-beta.4":
version: 2.0.0-beta.4
resolution: "@reduxjs/toolkit@npm:2.0.0-beta.4"
dependencies:
immer: ^10.0.2
redux: 5.0.0-beta.0
redux-thunk: 3.0.0-alpha.3
reselect: ^5.0.0-alpha.2
redux: ^5.0.0-beta.0
redux-thunk: ^3.0.0-beta.0
reselect: ^5.0.0-beta.0
peerDependencies:
react: ^16.9.0 || ^17.0.0 || ^18
react-redux: ^7.2.1 || ^8.0.2
react-redux: ^7.2.1 || ^8.0.2 || ^9.0.0-beta.0
peerDependenciesMeta:
react:
optional: true
react-redux:
optional: true
checksum: e03ecca1ef61d1073908095cb43215b3f8254c0a81872d44b0f49788ade72bf303bffd43dee57a8f8acebf76fade7e0bfb3d049189aed4467cb98b2e5e7c5b01
checksum: f7fe690b26840485a0dbc4a367424fc6c96604d8f6cab17ccb216ce1320d9a5c2f81c13d4e93d14095de6b0196ac742bff43b4834494be258ee42559e9dd429c
languageName: node
linkType: hard

Expand Down Expand Up @@ -2785,13 +2785,6 @@ __metadata:
languageName: node
linkType: hard

"@types/object-assign@npm:^4.0.30":
version: 4.0.30
resolution: "@types/object-assign@npm:4.0.30"
checksum: 24e0471ddcd578b7ea72d5174e9cd6b68d78b5fa00f9f48cee38713c0e2886c6c3478c53c04d0508d16deb4370eed71ed0bb1f5b9aaa406e61f07ffed5da1d3b
languageName: node
linkType: hard

"@types/prettier@npm:^2.1.5":
version: 2.7.3
resolution: "@types/prettier@npm:2.7.3"
Expand All @@ -2815,15 +2808,6 @@ __metadata:
languageName: node
linkType: hard

"@types/react-is@npm:^17":
version: 17.0.3
resolution: "@types/react-is@npm:17.0.3"
dependencies:
"@types/react": "*"
checksum: 6abb7c47d54f012272650df8a962a28bd82f219291e5ef8b4dfa7fe0bb98ae243b060bf9fbe8ceff6213141794855a006db194b490b00ffd15842ae19d0ce1f0
languageName: node
linkType: hard

"@types/react-native@npm:^0.67.4":
version: 0.67.4
resolution: "@types/react-native@npm:0.67.4"
Expand Down Expand Up @@ -9381,17 +9365,15 @@ __metadata:
"@babel/preset-env": ^7.12.1
"@babel/preset-typescript": ^7.14.5
"@microsoft/api-extractor": ^7.18.1
"@reduxjs/toolkit": ^2.0.0-beta.0
"@reduxjs/toolkit": ^2.0.0-beta.4
"@testing-library/jest-dom": ^5.11.5
"@testing-library/jest-native": ^3.4.3
"@testing-library/react": 13.0.0
"@testing-library/react-12": "npm:@testing-library/react@^12"
"@testing-library/react-hooks": ^3.4.2
"@testing-library/react-native": ^7.1.0
"@types/object-assign": ^4.0.30
"@types/react": ^18
"@types/react-dom": ^18
"@types/react-is": ^17
"@types/react-native": ^0.67.4
"@types/use-sync-external-store": ^0.0.3
"@typescript-eslint/eslint-plugin": ^4.28.0
Expand All @@ -9412,7 +9394,6 @@ __metadata:
prettier: ^2.1.2
react: 18.2.0
react-dom: 18.2.0
react-is: ^18.0.0
react-native: ^0.71.11
react-test-renderer: 18.0.0
redux: ^5.0.0-beta.0
Expand Down Expand Up @@ -9589,16 +9570,16 @@ __metadata:
languageName: node
linkType: hard

"redux-thunk@npm:3.0.0-alpha.3":
version: 3.0.0-alpha.3
resolution: "redux-thunk@npm:3.0.0-alpha.3"
"redux-thunk@npm:^3.0.0-beta.0":
version: 3.0.0-beta.0
resolution: "redux-thunk@npm:3.0.0-beta.0"
peerDependencies:
redux: ^4
checksum: a5be77887b422b3182ff7fae617ec552cd5f830afb326d83af32a430c3eb439c942a38c3691e5c975119e37787974172dbc0139f7782cbfaeea5c1292fa123ed
redux: ^4 || ^5.0.0-beta.0
checksum: 1609e18a9fb56ab7403d760999996b50e136fcf7411ec9d809e9a4afa4187bf0ab545652c05ffbfca2e0397e59e6baf2ae0d35631a30bf8ba20af1205e98e0fe
languageName: node
linkType: hard

"redux@npm:5.0.0-beta.0, redux@npm:^5.0.0-beta.0":
"redux@npm:^5.0.0-beta.0":
version: 5.0.0-beta.0
resolution: "redux@npm:5.0.0-beta.0"
checksum: 11df373e219f2f515ee1bda1a19a1ba5de02d8d5c874800ec353179dcd106eddd54432946fd0ab37c47f99f8fe53f820a6404c14da7f039a46022187e9469d2d
Expand Down Expand Up @@ -9738,10 +9719,10 @@ __metadata:
languageName: node
linkType: hard

"reselect@npm:^5.0.0-alpha.2":
version: 5.0.0-alpha.2
resolution: "reselect@npm:5.0.0-alpha.2"
checksum: c47b66999800e1297721cbc4b2464b520fade9823c598d578759c9fba3eb6be03b184e13c20f30820cc18fe2688fc9fb4475f83e59d8f2347aa0d591e465637d
"reselect@npm:^5.0.0-beta.0":
version: 5.0.0-beta.0
resolution: "reselect@npm:5.0.0-beta.0"
checksum: 462363aa730af93e396ff0d885f88fb8c43572b07f51c2a890d37f27edc3afecd300085916533e336142b3883f8532f35b5b1a2aaa1a70e9909aea48e5d3b98f
languageName: node
linkType: hard

Expand Down

0 comments on commit f1bf253

Please sign in to comment.