Skip to content

Commit

Permalink
Merge pull request #1951 from jspurlin/jspurlin/passOwnPropsToASE
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Sep 23, 2022
2 parents bbc546e + 527eb36 commit 69413ff
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
4 changes: 2 additions & 2 deletions docs/api/connect.md
Expand Up @@ -233,7 +233,7 @@ connect(mapStateToProps, mapDispatchToProps, null, { context: MyContext })(
)
```
#### `areStatesEqual: (next: Object, prev: Object) => boolean`
#### `areStatesEqual: (next: Object, prev: Object, nextOwnProps: Object, prevOwnProps: Object) => boolean`
- default value: `strictEqual: (next, prev) => prev === next`
Expand All @@ -244,7 +244,7 @@ const areStatesEqual = (next, prev) =>
prev.entities.todos === next.entities.todos
```
You may wish to override `areStatesEqual` if your `mapStateToProps` function is computationally expensive and is also only concerned with a small slice of your state. The example above will effectively ignore state changes for everything but that slice of state.
You may wish to override `areStatesEqual` if your `mapStateToProps` function is computationally expensive and is also only concerned with a small slice of your state. The example above will effectively ignore state changes for everything but that slice of state. Additionally, `areStatesEqual` provides `nextOwnProps` and `prevOwnProps` to allow for more effective scoping of your state which your connected component is interested in, if needed.
This would likely impact the other equality checks as well, depending on your `mapStateToProps` function.
Expand Down
9 changes: 7 additions & 2 deletions src/components/connect.tsx
Expand Up @@ -231,7 +231,12 @@ export interface ConnectOptions<
> {
forwardRef?: boolean
context?: typeof ReactReduxContext
areStatesEqual?: (nextState: State, prevState: State) => boolean
areStatesEqual?: (
nextState: State,
prevState: State,
nextOwnProps: TOwnProps,
prevOwnProps: TOwnProps
) => boolean

areOwnPropsEqual?: (
nextOwnProps: TOwnProps,
Expand Down Expand Up @@ -696,7 +701,7 @@ function connect<
notifyNestedSubs,
])

let actualChildProps: uSES
let actualChildProps: Record<string, unknown>

try {
actualChildProps = useSyncExternalStore(
Expand Down
11 changes: 8 additions & 3 deletions src/connect/selectorFactory.ts
@@ -1,7 +1,7 @@
import type { Dispatch, Action } from 'redux'
import type { ComponentType } from 'react'
import verifySubselectors from './verifySubselectors'
import type { EqualityFn } from '../types'
import type { EqualityFn, ExtendedEqualityFn } from '../types'

export type SelectorFactory<S, TProps, TOwnProps, TFactoryOptions> = (
dispatch: Dispatch<Action<unknown>>,
Expand Down Expand Up @@ -59,7 +59,7 @@ export type MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps> = (
) => TMergedProps

interface PureSelectorFactoryComparisonOptions<TStateProps, TOwnProps, State> {
readonly areStatesEqual: EqualityFn<State>
readonly areStatesEqual: ExtendedEqualityFn<State, TOwnProps>
readonly areStatePropsEqual: EqualityFn<TStateProps>
readonly areOwnPropsEqual: EqualityFn<TOwnProps>
}
Expand Down Expand Up @@ -132,7 +132,12 @@ export function pureFinalPropsSelectorFactory<

function handleSubsequentCalls(nextState: State, nextOwnProps: TOwnProps) {
const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps)
const stateChanged = !areStatesEqual(nextState, state)
const stateChanged = !areStatesEqual(
nextState,
state,
nextOwnProps,
ownProps
)
state = nextState
ownProps = nextOwnProps

Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Expand Up @@ -15,6 +15,8 @@ export type FixTypeLater = any

export type EqualityFn<T> = (a: T, b: T) => boolean

export type ExtendedEqualityFn<T, P> = (a: T, b: T, c: P, d: P) => boolean

export type AnyIfEmpty<T extends object> = keyof T extends never ? any : T

export type DistributiveOmit<T, K extends keyof T> = T extends unknown
Expand Down

0 comments on commit 69413ff

Please sign in to comment.