From 18c2b89f8191c99bde00d6d2a9c382f8eaf5f8ca Mon Sep 17 00:00:00 2001 From: Julien Deniau <1398469+jdeniau@users.noreply.github.com> Date: Tue, 14 Nov 2023 03:56:18 +0100 Subject: [PATCH 1/8] Typo : extra `;` in code block (#2083) --- .../connect-extracting-data-with-mapStateToProps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-react-redux/connect-extracting-data-with-mapStateToProps.md b/docs/using-react-redux/connect-extracting-data-with-mapStateToProps.md index 6f3ff30cb..ea3fd4deb 100644 --- a/docs/using-react-redux/connect-extracting-data-with-mapStateToProps.md +++ b/docs/using-react-redux/connect-extracting-data-with-mapStateToProps.md @@ -69,7 +69,7 @@ function mapStateToProps(state, ownProps) { } // Later, in your application, a parent component renders: -; + // and your component receives props.id, props.todo, and props.visibilityFilter ``` From dbeec9e5da328f24340be1560b27ed09bc033d9c Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 16:31:50 -0600 Subject: [PATCH 2/8] Rename `noopCheck` to `identityFunctionCheck` --- docs/api/hooks.md | 10 +++++----- src/components/Context.ts | 6 +++--- src/components/Provider.tsx | 10 +++++----- src/hooks/useSelector.ts | 22 +++++++++++----------- test/hooks/useSelector.spec.tsx | 10 +++++----- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/api/hooks.md b/docs/api/hooks.md index 90ba18fdd..ed0f3c252 100644 --- a/docs/api/hooks.md +++ b/docs/api/hooks.md @@ -53,7 +53,7 @@ export type CheckFrequency = 'never' | 'once' | 'always' interface UseSelectorOptions { equalityFn?: EqualityFn stabilityCheck?: CheckFrequency - noopCheck?: CheckFrequency + identityFunctionCheck?: CheckFrequency } const result: Selected = useSelector( @@ -303,7 +303,7 @@ function Component() { } ``` -#### No-op selector check +#### `identityFunctionCheck` In development, a check is conducted on the result returned by the selector. It warns in the console if the result is the same as the parameter passed in, i.e. the root state. @@ -321,16 +321,16 @@ const user = useSelector((state) => state.auth.currentUser) By default, this will only happen when the selector is first called. You can configure the check in the Provider or at each `useSelector` call. ```tsx title="Global setting via context" - + {children} ``` ```tsx title="Individual hook setting" function Component() { - const count = useSelector(selectCount, { noopCheck: 'never' }) + const count = useSelector(selectCount, { identityFunctionCheck: 'never' }) // run once (default) - const user = useSelector(selectUser, { noopCheck: 'once' }) + const user = useSelector(selectUser, { identityFunctionCheck: 'once' }) // ... } ``` diff --git a/src/components/Context.ts b/src/components/Context.ts index 993d6613a..f4424b685 100644 --- a/src/components/Context.ts +++ b/src/components/Context.ts @@ -1,8 +1,8 @@ -import * as React from 'react' import type { Context } from 'react' +import * as React from 'react' import type { Action, Store, UnknownAction } from 'redux' -import type { Subscription } from '../utils/Subscription' import type { CheckFrequency } from '../hooks/useSelector' +import type { Subscription } from '../utils/Subscription' export interface ReactReduxContextValue< SS = any, @@ -12,7 +12,7 @@ export interface ReactReduxContextValue< subscription: Subscription getServerState?: () => SS stabilityCheck: CheckFrequency - noopCheck: CheckFrequency + identityFunctionCheck: CheckFrequency } const ContextKey = Symbol.for(`react-redux-context`) diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index 7ddfc7e89..970d22d6d 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -32,8 +32,8 @@ export interface ProviderProps< /** Global configuration for the `useSelector` stability check */ stabilityCheck?: CheckFrequency - /** Global configuration for the `useSelector` no-op check */ - noopCheck?: CheckFrequency + /** Global configuration for the `useSelector` identity function check */ + identityFunctionCheck?: CheckFrequency children: ReactNode } @@ -44,7 +44,7 @@ function Provider = UnknownAction, S = unknown>({ children, serverState, stabilityCheck = 'once', - noopCheck = 'once', + identityFunctionCheck = 'once', }: ProviderProps) { const contextValue = React.useMemo(() => { const subscription = createSubscription(store) @@ -53,9 +53,9 @@ function Provider = UnknownAction, S = unknown>({ subscription, getServerState: serverState ? () => serverState : undefined, stabilityCheck, - noopCheck, + identityFunctionCheck, } - }, [store, serverState, stabilityCheck, noopCheck]) + }, [store, serverState, stabilityCheck, identityFunctionCheck]) const previousState = React.useMemo(() => store.getState(), [store]) diff --git a/src/hooks/useSelector.ts b/src/hooks/useSelector.ts index e9a34838f..7ef14c9e4 100644 --- a/src/hooks/useSelector.ts +++ b/src/hooks/useSelector.ts @@ -1,21 +1,21 @@ import * as React from 'react' -import { - createReduxContextHook, - useReduxContext as useDefaultReduxContext, -} from './useReduxContext' import type { ReactReduxContextValue } from '../components/Context' import { ReactReduxContext } from '../components/Context' import type { EqualityFn, NoInfer } from '../types' import type { uSESWS } from '../utils/useSyncExternalStore' import { notInitialized } from '../utils/useSyncExternalStore' +import { + createReduxContextHook, + useReduxContext as useDefaultReduxContext, +} from './useReduxContext' export type CheckFrequency = 'never' | 'once' | 'always' export interface UseSelectorOptions { equalityFn?: EqualityFn stabilityCheck?: CheckFrequency - noopCheck?: CheckFrequency + identityFunctionCheck?: CheckFrequency } export interface UseSelector { @@ -62,7 +62,7 @@ export function createSelectorHook( const { equalityFn = refEquality, stabilityCheck = undefined, - noopCheck = undefined, + identityFunctionCheck = undefined, } = typeof equalityFnOrOptions === 'function' ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions @@ -85,7 +85,7 @@ export function createSelectorHook( subscription, getServerState, stabilityCheck: globalStabilityCheck, - noopCheck: globalNoopCheck, + identityFunctionCheck: globalIdentityFunctionCheck, } = useReduxContext() const firstRun = React.useRef(true) @@ -125,11 +125,11 @@ export function createSelectorHook( ) } } - const finalNoopCheck = - typeof noopCheck === 'undefined' ? globalNoopCheck : noopCheck + const finalIdentityFunctionCheck = + typeof identityFunctionCheck === 'undefined' ? globalIdentityFunctionCheck : identityFunctionCheck if ( - finalNoopCheck === 'always' || - (finalNoopCheck === 'once' && firstRun.current) + finalIdentityFunctionCheck === 'always' || + (finalIdentityFunctionCheck === 'once' && firstRun.current) ) { // @ts-ignore if (selected === state) { diff --git a/test/hooks/useSelector.spec.tsx b/test/hooks/useSelector.spec.tsx index debc1c426..752d62bd1 100644 --- a/test/hooks/useSelector.spec.tsx +++ b/test/hooks/useSelector.spec.tsx @@ -33,14 +33,14 @@ import type { UseSelectorOptions } from '../../src/hooks/useSelector' // disable checks by default function ProviderMock = AnyAction, S = unknown>({ stabilityCheck = 'never', - noopCheck = 'never', + identityFunctionCheck = 'never', ...props }: ProviderProps) { return ( ) } @@ -1028,10 +1028,10 @@ describe('React', () => { expect(selector).toHaveBeenCalledTimes(4) }) }) - describe('no-op selector check', () => { + describe('identity function check', () => { it('warns for selectors that return the entire root state', () => { rtl.render( - + state.count} /> ) @@ -1041,7 +1041,7 @@ describe('React', () => { rtl.cleanup() rtl.render( - + state} /> ) From 471372125d48659736b717ec15de93750f1ac7f2 Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 17:05:32 -0600 Subject: [PATCH 3/8] Rename `CheckFrequency` to `DevModeCheckFrequency` --- src/components/Context.ts | 6 +++--- src/components/Provider.tsx | 12 ++++++------ src/hooks/useSelector.ts | 16 ++++++++++++---- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/Context.ts b/src/components/Context.ts index f4424b685..3bdf74022 100644 --- a/src/components/Context.ts +++ b/src/components/Context.ts @@ -1,7 +1,7 @@ import type { Context } from 'react' import * as React from 'react' import type { Action, Store, UnknownAction } from 'redux' -import type { CheckFrequency } from '../hooks/useSelector' +import type { DevModeCheckFrequency } from '../hooks/useSelector' import type { Subscription } from '../utils/Subscription' export interface ReactReduxContextValue< @@ -11,8 +11,8 @@ export interface ReactReduxContextValue< store: Store subscription: Subscription getServerState?: () => SS - stabilityCheck: CheckFrequency - identityFunctionCheck: CheckFrequency + stabilityCheck: DevModeCheckFrequency + identityFunctionCheck: DevModeCheckFrequency } const ContextKey = Symbol.for(`react-redux-context`) diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index 970d22d6d..32604c8f8 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -1,11 +1,11 @@ import type { Context, ReactNode } from 'react' import * as React from 'react' -import type { ReactReduxContextValue } from './Context' -import { ReactReduxContext } from './Context' +import type { Action, Store, UnknownAction } from 'redux' +import type { DevModeCheckFrequency } from '../hooks/useSelector' import { createSubscription } from '../utils/Subscription' import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect' -import type { Action, Store, UnknownAction } from 'redux' -import type { CheckFrequency } from '../hooks/useSelector' +import type { ReactReduxContextValue } from './Context' +import { ReactReduxContext } from './Context' export interface ProviderProps< A extends Action = UnknownAction, @@ -30,10 +30,10 @@ export interface ProviderProps< context?: Context | null> /** Global configuration for the `useSelector` stability check */ - stabilityCheck?: CheckFrequency + stabilityCheck?: DevModeCheckFrequency /** Global configuration for the `useSelector` identity function check */ - identityFunctionCheck?: CheckFrequency + identityFunctionCheck?: DevModeCheckFrequency children: ReactNode } diff --git a/src/hooks/useSelector.ts b/src/hooks/useSelector.ts index 7ef14c9e4..bedc777be 100644 --- a/src/hooks/useSelector.ts +++ b/src/hooks/useSelector.ts @@ -10,12 +10,18 @@ import { useReduxContext as useDefaultReduxContext, } from './useReduxContext' -export type CheckFrequency = 'never' | 'once' | 'always' +/** + * The frequency of development mode checks. + * + * @since 8.1.0 + * @internal + */ +export type DevModeCheckFrequency = 'never' | 'once' | 'always' export interface UseSelectorOptions { equalityFn?: EqualityFn - stabilityCheck?: CheckFrequency - identityFunctionCheck?: CheckFrequency + stabilityCheck?: DevModeCheckFrequency + identityFunctionCheck?: DevModeCheckFrequency } export interface UseSelector { @@ -126,7 +132,9 @@ export function createSelectorHook( } } const finalIdentityFunctionCheck = - typeof identityFunctionCheck === 'undefined' ? globalIdentityFunctionCheck : identityFunctionCheck + typeof identityFunctionCheck === 'undefined' + ? globalIdentityFunctionCheck + : identityFunctionCheck if ( finalIdentityFunctionCheck === 'always' || (finalIdentityFunctionCheck === 'once' && firstRun.current) From e8ed4b677d769d12bd5e6e95525d0d668d961532 Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 17:07:19 -0600 Subject: [PATCH 4/8] Rename `CheckFrequency` to `DevModeCheckFrequency` in docs --- docs/api/hooks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/hooks.md b/docs/api/hooks.md index ed0f3c252..894c9d012 100644 --- a/docs/api/hooks.md +++ b/docs/api/hooks.md @@ -48,12 +48,12 @@ From there, you may import any of the listed React Redux hooks APIs and use them type RootState = ReturnType type SelectorFn = (state: RootState) => Selected type EqualityFn = (a: any, b: any) => boolean -export type CheckFrequency = 'never' | 'once' | 'always' +export type DevModeCheckFrequency = 'never' | 'once' | 'always' interface UseSelectorOptions { equalityFn?: EqualityFn - stabilityCheck?: CheckFrequency - identityFunctionCheck?: CheckFrequency + stabilityCheck?: DevModeCheckFrequency + identityFunctionCheck?: DevModeCheckFrequency } const result: Selected = useSelector( From b0b42635db15a6886f9eb9ef03a80d3f75e3d7e7 Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 18:05:56 -0600 Subject: [PATCH 5/8] Add `devModeChecks` to `useSelector` --- src/components/Context.ts | 6 +-- src/components/Provider.tsx | 18 +++++++- src/hooks/useSelector.ts | 76 ++++++++++++++++++++++++--------- test/hooks/useSelector.spec.tsx | 40 ++++++++--------- test/typetests/hooks.tsx | 31 ++++---------- 5 files changed, 102 insertions(+), 69 deletions(-) diff --git a/src/components/Context.ts b/src/components/Context.ts index 3bdf74022..006942227 100644 --- a/src/components/Context.ts +++ b/src/components/Context.ts @@ -1,18 +1,16 @@ import type { Context } from 'react' import * as React from 'react' import type { Action, Store, UnknownAction } from 'redux' -import type { DevModeCheckFrequency } from '../hooks/useSelector' import type { Subscription } from '../utils/Subscription' +import type { ProviderProps } from './Provider' export interface ReactReduxContextValue< SS = any, A extends Action = UnknownAction -> { +> extends Pick { store: Store subscription: Subscription getServerState?: () => SS - stabilityCheck: DevModeCheckFrequency - identityFunctionCheck: DevModeCheckFrequency } const ContextKey = Symbol.for(`react-redux-context`) diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index 32604c8f8..5680f2183 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -29,10 +29,24 @@ export interface ProviderProps< */ context?: Context | null> - /** Global configuration for the `useSelector` stability check */ + /** + * Determines the frequency of stability checks for all selectors. + * This setting overrides the global configuration for + * the `useSelector` stability check, allowing you to specify how often + * these checks should occur in development mode. + * + * @since 8.1.0 + */ stabilityCheck?: DevModeCheckFrequency - /** Global configuration for the `useSelector` identity function check */ + /** + * Determines the frequency of identity function checks for all selectors. + * This setting overrides the global configuration for + * the `useSelector` identity function check, allowing you to specify how often + * these checks should occur in development mode. + * + * @since 9.0.0 + */ identityFunctionCheck?: DevModeCheckFrequency children: ReactNode diff --git a/src/hooks/useSelector.ts b/src/hooks/useSelector.ts index bedc777be..ae6b53d90 100644 --- a/src/hooks/useSelector.ts +++ b/src/hooks/useSelector.ts @@ -18,10 +18,49 @@ import { */ export type DevModeCheckFrequency = 'never' | 'once' | 'always' +/** + * Represents the configuration for development mode checks. + * + * @since 9.0.0 + * @internal + */ +export interface DevModeChecks { + /** + * Overrides the global stability check for the selector. + * - `once` - Run only the first time the selector is called. + * - `always` - Run every time the selector is called. + * - `never` - Never run the stability check. + * + * @default 'once' + * + * @since 8.1.0 + */ + stabilityCheck: DevModeCheckFrequency + + /** + * Overrides the global identity function check for the selector. + * - `once` - Run only the first time the selector is called. + * - `always` - Run every time the selector is called. + * - `never` - Never run the identity function check. + * + * @default 'once' + * + * @since 9.0.0 + */ + identityFunctionCheck: DevModeCheckFrequency +} + export interface UseSelectorOptions { equalityFn?: EqualityFn - stabilityCheck?: DevModeCheckFrequency - identityFunctionCheck?: DevModeCheckFrequency + + /** + * `useSelector` performs additional checks in development mode to help + * identify and warn about potential issues in selector behavior. This + * option allows you to customize the behavior of these checks per selector. + * + * @since 9.0.0 + */ + devModeChecks?: Partial } export interface UseSelector { @@ -65,13 +104,10 @@ export function createSelectorHook( | EqualityFn> | UseSelectorOptions> = {} ): Selected { - const { - equalityFn = refEquality, - stabilityCheck = undefined, - identityFunctionCheck = undefined, - } = typeof equalityFnOrOptions === 'function' - ? { equalityFn: equalityFnOrOptions } - : equalityFnOrOptions + const { equalityFn = refEquality, devModeChecks = {} } = + typeof equalityFnOrOptions === 'function' + ? { equalityFn: equalityFnOrOptions } + : equalityFnOrOptions if (process.env.NODE_ENV !== 'production') { if (!selector) { throw new Error(`You must pass a selector to useSelector`) @@ -90,8 +126,8 @@ export function createSelectorHook( store, subscription, getServerState, - stabilityCheck: globalStabilityCheck, - identityFunctionCheck: globalIdentityFunctionCheck, + stabilityCheck, + identityFunctionCheck, } = useReduxContext() const firstRun = React.useRef(true) @@ -101,10 +137,14 @@ export function createSelectorHook( [selector.name](state: TState) { const selected = selector(state) if (process.env.NODE_ENV !== 'production') { - const finalStabilityCheck = - typeof stabilityCheck === 'undefined' - ? globalStabilityCheck - : stabilityCheck + const { + identityFunctionCheck: finalIdentityFunctionCheck, + stabilityCheck: finalStabilityCheck, + } = { + stabilityCheck, + identityFunctionCheck, + ...devModeChecks, + } if ( finalStabilityCheck === 'always' || (finalStabilityCheck === 'once' && firstRun.current) @@ -131,10 +171,6 @@ export function createSelectorHook( ) } } - const finalIdentityFunctionCheck = - typeof identityFunctionCheck === 'undefined' - ? globalIdentityFunctionCheck - : identityFunctionCheck if ( finalIdentityFunctionCheck === 'always' || (finalIdentityFunctionCheck === 'once' && firstRun.current) @@ -161,7 +197,7 @@ export function createSelectorHook( return selected }, }[selector.name], - [selector, globalStabilityCheck, stabilityCheck] + [selector, stabilityCheck, devModeChecks.stabilityCheck] ) const selectedState = useSyncExternalStoreWithSelector( diff --git a/test/hooks/useSelector.spec.tsx b/test/hooks/useSelector.spec.tsx index 752d62bd1..9108d18ff 100644 --- a/test/hooks/useSelector.spec.tsx +++ b/test/hooks/useSelector.spec.tsx @@ -1,34 +1,34 @@ /*eslint-disable react/prop-types*/ +import * as rtl from '@testing-library/react' +import type { DispatchWithoutAction, FunctionComponent, ReactNode } from 'react' import React, { + Suspense, useCallback, - useReducer, - useLayoutEffect, - useState, useContext, - Suspense, useEffect, + useLayoutEffect, + useReducer, + useState, } from 'react' +import type { Action, AnyAction, Store } from 'redux' import { createStore } from 'redux' -import * as rtl from '@testing-library/react' +import type { UseSelectorOptions } from '../../src/hooks/useSelector' +import type { + ProviderProps, + ReactReduxContextValue, + Subscription, + TypedUseSelectorHook, +} from '../../src/index' import { Provider, - useSelector, - useDispatch, - shallowEqual, + ReactReduxContext, connect, createSelectorHook, - ReactReduxContext, -} from '../../src/index' -import type { - TypedUseSelectorHook, - ReactReduxContextValue, - ProviderProps, - Subscription, + shallowEqual, + useDispatch, + useSelector, } from '../../src/index' -import type { FunctionComponent, DispatchWithoutAction, ReactNode } from 'react' -import type { Store, AnyAction, Action } from 'redux' -import type { UseSelectorOptions } from '../../src/hooks/useSelector' // disable checks by default function ProviderMock = AnyAction, S = unknown>({ @@ -984,7 +984,7 @@ describe('React', () => { ) @@ -1014,7 +1014,7 @@ describe('React', () => { ) diff --git a/test/typetests/hooks.tsx b/test/typetests/hooks.tsx index c35cc0be2..a553ed29e 100644 --- a/test/typetests/hooks.tsx +++ b/test/typetests/hooks.tsx @@ -1,42 +1,27 @@ /* eslint-disable @typescript-eslint/no-unused-vars, no-inner-declarations */ -import * as React from 'react' -import * as ReactDOM from 'react-dom' -import type { Store, Dispatch, AnyAction } from '@reduxjs/toolkit' +import type { AnyAction, Dispatch, Store } from '@reduxjs/toolkit' import { configureStore } from '@reduxjs/toolkit' +import * as React from 'react' import type { ReactReduxContextValue, Selector, TypedUseSelectorHook, } from '../../src/index' import { - connect, - ConnectedProps, - Provider, - DispatchProp, - MapStateToProps, - ReactReduxContext, + createDispatchHook, + createSelectorHook, + createStoreHook, shallowEqual, - MapDispatchToProps, useDispatch, useSelector, useStore, - createDispatchHook, - createSelectorHook, - createStoreHook, } from '../../src/index' import type { AppDispatch, RootState } from './counterApp' -import { - CounterState, - counterSlice, - increment, - incrementAsync, - AppThunk, - fetchCount, -} from './counterApp' +import { incrementAsync } from './counterApp' -import { expectType, expectExactType } from '../typeTestHelpers' +import { expectExactType, expectType } from '../typeTestHelpers' function preTypedHooksSetup() { // Standard hooks setup @@ -172,7 +157,7 @@ function testUseSelector() { const correctlyInferred: State = useSelector(selector, shallowEqual) const correctlyInferred2: State = useSelector(selector, { equalityFn: shallowEqual, - stabilityCheck: 'never', + devModeChecks: { stabilityCheck: 'never' }, }) // @ts-expect-error const inferredTypeIsNotString: string = useSelector(selector, shallowEqual) From ad2ec13cd4499366f20759abf95cc6fb4002299c Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 18:13:20 -0600 Subject: [PATCH 6/8] Add previously referred to as `noopCheck` to JSDocs --- src/components/Provider.tsx | 2 ++ src/hooks/useSelector.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index 5680f2183..e93a94fad 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -45,6 +45,8 @@ export interface ProviderProps< * the `useSelector` identity function check, allowing you to specify how often * these checks should occur in development mode. * + * **Note**: Previously referred to as `noopCheck`. + * * @since 9.0.0 */ identityFunctionCheck?: DevModeCheckFrequency diff --git a/src/hooks/useSelector.ts b/src/hooks/useSelector.ts index ae6b53d90..9f1d7b697 100644 --- a/src/hooks/useSelector.ts +++ b/src/hooks/useSelector.ts @@ -43,6 +43,8 @@ export interface DevModeChecks { * - `always` - Run every time the selector is called. * - `never` - Never run the identity function check. * + * **Note**: Previously referred to as `noopCheck`. + * * @default 'once' * * @since 9.0.0 From 05f535127772150a0e6007a83c13f2e450e9a128 Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 18:17:37 -0600 Subject: [PATCH 7/8] Add `devModeChecks` to `hooks.md` --- docs/api/hooks.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/hooks.md b/docs/api/hooks.md index 894c9d012..e6b926d00 100644 --- a/docs/api/hooks.md +++ b/docs/api/hooks.md @@ -52,8 +52,10 @@ export type DevModeCheckFrequency = 'never' | 'once' | 'always' interface UseSelectorOptions { equalityFn?: EqualityFn - stabilityCheck?: DevModeCheckFrequency - identityFunctionCheck?: DevModeCheckFrequency + devModeChecks?: { + stabilityCheck?: DevModeCheckFrequency + identityFunctionCheck?: DevModeCheckFrequency + } } const result: Selected = useSelector( From 07f306052cc50154d86f8a3e9bf944f931ffdde9 Mon Sep 17 00:00:00 2001 From: Arya Emami Date: Sat, 2 Dec 2023 18:36:14 -0600 Subject: [PATCH 8/8] Add breaking change warning to docs --- docs/api/hooks.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/api/hooks.md b/docs/api/hooks.md index e6b926d00..6ed03157c 100644 --- a/docs/api/hooks.md +++ b/docs/api/hooks.md @@ -298,14 +298,24 @@ By default, this will only happen when the selector is first called. You can con ```tsx title="Individual hook setting" function Component() { - const count = useSelector(selectCount, { stabilityCheck: 'never' }) + const count = useSelector(selectCount, { + devModeChecks: { stabilityCheck: 'never' }, + }) // run once (default) - const user = useSelector(selectUser, { stabilityCheck: 'once' }) + const user = useSelector(selectUser, { + devModeChecks: { stabilityCheck: 'once' }, + }) // ... } ``` -#### `identityFunctionCheck` +#### Identity Function (`state => state`) Check + +:::danger Breaking Change! + +This was previously referred to as `noopCheck`. + +::: In development, a check is conducted on the result returned by the selector. It warns in the console if the result is the same as the parameter passed in, i.e. the root state. @@ -330,9 +340,13 @@ By default, this will only happen when the selector is first called. You can con ```tsx title="Individual hook setting" function Component() { - const count = useSelector(selectCount, { identityFunctionCheck: 'never' }) + const count = useSelector(selectCount, { + devModeChecks: { identityFunctionCheck: 'never' }, + }) // run once (default) - const user = useSelector(selectUser, { identityFunctionCheck: 'once' }) + const user = useSelector(selectUser, { + devModeChecks: { identityFunctionCheck: 'once' }, + }) // ... } ```