1
1
import * as React from 'react'
2
2
3
- import {
4
- createReduxContextHook ,
5
- useReduxContext as useDefaultReduxContext ,
6
- } from './useReduxContext'
7
3
import type { ReactReduxContextValue } from '../components/Context'
8
4
import { ReactReduxContext } from '../components/Context'
9
5
import type { EqualityFn , NoInfer } from '../types'
10
6
import type { uSESWS } from '../utils/useSyncExternalStore'
11
7
import { notInitialized } from '../utils/useSyncExternalStore'
8
+ import {
9
+ createReduxContextHook ,
10
+ useReduxContext as useDefaultReduxContext ,
11
+ } from './useReduxContext'
12
+
13
+ /**
14
+ * The frequency of development mode checks.
15
+ *
16
+ * @since 8.1.0
17
+ * @internal
18
+ */
19
+ export type DevModeCheckFrequency = 'never' | 'once' | 'always'
20
+
21
+ /**
22
+ * Represents the configuration for development mode checks.
23
+ *
24
+ * @since 9.0.0
25
+ * @internal
26
+ */
27
+ export interface DevModeChecks {
28
+ /**
29
+ * Overrides the global stability check for the selector.
30
+ * - `once` - Run only the first time the selector is called.
31
+ * - `always` - Run every time the selector is called.
32
+ * - `never` - Never run the stability check.
33
+ *
34
+ * @default 'once'
35
+ *
36
+ * @since 8.1.0
37
+ */
38
+ stabilityCheck : DevModeCheckFrequency
12
39
13
- export type CheckFrequency = 'never' | 'once' | 'always'
40
+ /**
41
+ * Overrides the global identity function check for the selector.
42
+ * - `once` - Run only the first time the selector is called.
43
+ * - `always` - Run every time the selector is called.
44
+ * - `never` - Never run the identity function check.
45
+ *
46
+ * **Note**: Previously referred to as `noopCheck`.
47
+ *
48
+ * @default 'once'
49
+ *
50
+ * @since 9.0.0
51
+ */
52
+ identityFunctionCheck : DevModeCheckFrequency
53
+ }
14
54
15
55
export interface UseSelectorOptions < Selected = unknown > {
16
56
equalityFn ?: EqualityFn < Selected >
17
- stabilityCheck ?: CheckFrequency
18
- noopCheck ?: CheckFrequency
57
+
58
+ /**
59
+ * `useSelector` performs additional checks in development mode to help
60
+ * identify and warn about potential issues in selector behavior. This
61
+ * option allows you to customize the behavior of these checks per selector.
62
+ *
63
+ * @since 9.0.0
64
+ */
65
+ devModeChecks ?: Partial < DevModeChecks >
19
66
}
20
67
21
68
export interface UseSelector {
@@ -59,13 +106,10 @@ export function createSelectorHook(
59
106
| EqualityFn < NoInfer < Selected > >
60
107
| UseSelectorOptions < NoInfer < Selected > > = { }
61
108
) : Selected {
62
- const {
63
- equalityFn = refEquality ,
64
- stabilityCheck = undefined ,
65
- noopCheck = undefined ,
66
- } = typeof equalityFnOrOptions === 'function'
67
- ? { equalityFn : equalityFnOrOptions }
68
- : equalityFnOrOptions
109
+ const { equalityFn = refEquality , devModeChecks = { } } =
110
+ typeof equalityFnOrOptions === 'function'
111
+ ? { equalityFn : equalityFnOrOptions }
112
+ : equalityFnOrOptions
69
113
if ( process . env . NODE_ENV !== 'production' ) {
70
114
if ( ! selector ) {
71
115
throw new Error ( `You must pass a selector to useSelector` )
@@ -84,8 +128,8 @@ export function createSelectorHook(
84
128
store,
85
129
subscription,
86
130
getServerState,
87
- stabilityCheck : globalStabilityCheck ,
88
- noopCheck : globalNoopCheck ,
131
+ stabilityCheck,
132
+ identityFunctionCheck ,
89
133
} = useReduxContext ( )
90
134
91
135
const firstRun = React . useRef ( true )
@@ -95,10 +139,14 @@ export function createSelectorHook(
95
139
[ selector . name ] ( state : TState ) {
96
140
const selected = selector ( state )
97
141
if ( process . env . NODE_ENV !== 'production' ) {
98
- const finalStabilityCheck =
99
- typeof stabilityCheck === 'undefined'
100
- ? globalStabilityCheck
101
- : stabilityCheck
142
+ const {
143
+ identityFunctionCheck : finalIdentityFunctionCheck ,
144
+ stabilityCheck : finalStabilityCheck ,
145
+ } = {
146
+ stabilityCheck,
147
+ identityFunctionCheck,
148
+ ...devModeChecks ,
149
+ }
102
150
if (
103
151
finalStabilityCheck === 'always' ||
104
152
( finalStabilityCheck === 'once' && firstRun . current )
@@ -125,11 +173,9 @@ export function createSelectorHook(
125
173
)
126
174
}
127
175
}
128
- const finalNoopCheck =
129
- typeof noopCheck === 'undefined' ? globalNoopCheck : noopCheck
130
176
if (
131
- finalNoopCheck === 'always' ||
132
- ( finalNoopCheck === 'once' && firstRun . current )
177
+ finalIdentityFunctionCheck === 'always' ||
178
+ ( finalIdentityFunctionCheck === 'once' && firstRun . current )
133
179
) {
134
180
// @ts -ignore
135
181
if ( selected === state ) {
@@ -153,7 +199,7 @@ export function createSelectorHook(
153
199
return selected
154
200
} ,
155
201
} [ selector . name ] ,
156
- [ selector , globalStabilityCheck , stabilityCheck ]
202
+ [ selector , stabilityCheck , devModeChecks . stabilityCheck ]
157
203
)
158
204
159
205
const selectedState = useSyncExternalStoreWithSelector (
0 commit comments