@depup/reduxjs__toolkit 2.12.0-depup.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -0
  3. package/changes.json +18 -0
  4. package/dist/cjs/index.js +6 -0
  5. package/dist/cjs/redux-toolkit.development.cjs +2406 -0
  6. package/dist/cjs/redux-toolkit.development.cjs.map +1 -0
  7. package/dist/cjs/redux-toolkit.production.min.cjs +3 -0
  8. package/dist/cjs/redux-toolkit.production.min.cjs.map +1 -0
  9. package/dist/index.d.mts +2665 -0
  10. package/dist/index.d.ts +2665 -0
  11. package/dist/query/cjs/index.js +6 -0
  12. package/dist/query/cjs/rtk-query.development.cjs +3092 -0
  13. package/dist/query/cjs/rtk-query.development.cjs.map +1 -0
  14. package/dist/query/cjs/rtk-query.production.min.cjs +2 -0
  15. package/dist/query/cjs/rtk-query.production.min.cjs.map +1 -0
  16. package/dist/query/index.d.mts +3066 -0
  17. package/dist/query/index.d.ts +3066 -0
  18. package/dist/query/react/cjs/index.js +6 -0
  19. package/dist/query/react/cjs/rtk-query-react.development.cjs +748 -0
  20. package/dist/query/react/cjs/rtk-query-react.development.cjs.map +1 -0
  21. package/dist/query/react/cjs/rtk-query-react.production.min.cjs +2 -0
  22. package/dist/query/react/cjs/rtk-query-react.production.min.cjs.map +1 -0
  23. package/dist/query/react/index.d.mts +1009 -0
  24. package/dist/query/react/index.d.ts +1009 -0
  25. package/dist/query/react/rtk-query-react.browser.mjs +2 -0
  26. package/dist/query/react/rtk-query-react.browser.mjs.map +1 -0
  27. package/dist/query/react/rtk-query-react.legacy-esm.js +740 -0
  28. package/dist/query/react/rtk-query-react.legacy-esm.js.map +1 -0
  29. package/dist/query/react/rtk-query-react.modern.mjs +705 -0
  30. package/dist/query/react/rtk-query-react.modern.mjs.map +1 -0
  31. package/dist/query/rtk-query.browser.mjs +2 -0
  32. package/dist/query/rtk-query.browser.mjs.map +1 -0
  33. package/dist/query/rtk-query.legacy-esm.js +3117 -0
  34. package/dist/query/rtk-query.legacy-esm.js.map +1 -0
  35. package/dist/query/rtk-query.modern.mjs +3052 -0
  36. package/dist/query/rtk-query.modern.mjs.map +1 -0
  37. package/dist/react/cjs/index.js +6 -0
  38. package/dist/react/cjs/redux-toolkit-react.development.cjs +55 -0
  39. package/dist/react/cjs/redux-toolkit-react.development.cjs.map +1 -0
  40. package/dist/react/cjs/redux-toolkit-react.production.min.cjs +2 -0
  41. package/dist/react/cjs/redux-toolkit-react.production.min.cjs.map +1 -0
  42. package/dist/react/index.d.mts +22 -0
  43. package/dist/react/index.d.ts +22 -0
  44. package/dist/react/redux-toolkit-react.browser.mjs +2 -0
  45. package/dist/react/redux-toolkit-react.browser.mjs.map +1 -0
  46. package/dist/react/redux-toolkit-react.legacy-esm.js +47 -0
  47. package/dist/react/redux-toolkit-react.legacy-esm.js.map +1 -0
  48. package/dist/react/redux-toolkit-react.modern.mjs +28 -0
  49. package/dist/react/redux-toolkit-react.modern.mjs.map +1 -0
  50. package/dist/redux-toolkit.browser.mjs +3 -0
  51. package/dist/redux-toolkit.browser.mjs.map +1 -0
  52. package/dist/redux-toolkit.legacy-esm.js +2351 -0
  53. package/dist/redux-toolkit.legacy-esm.js.map +1 -0
  54. package/dist/redux-toolkit.modern.mjs +2330 -0
  55. package/dist/redux-toolkit.modern.mjs.map +1 -0
  56. package/dist/uncheckedindexed.ts +16 -0
  57. package/package.json +310 -0
  58. package/query/package.json +13 -0
  59. package/query/react/package.json +13 -0
  60. package/react/package.json +13 -0
  61. package/skills/build-modern-redux-apps/modern-redux/SKILL.md +304 -0
  62. package/skills/build-modern-redux-apps/modern-redux/references/store-lifetime.md +53 -0
  63. package/skills/build-modern-redux-apps/redux-dataflow/SKILL.md +264 -0
  64. package/skills/evolve-and-diagnose-redux-apps/debug-redux-toolkit-apps/SKILL.md +269 -0
  65. package/skills/evolve-and-diagnose-redux-apps/migrate-to-modern-redux/SKILL.md +226 -0
  66. package/skills/manage-server-data/adopt-rtk-query/SKILL.md +385 -0
  67. package/skills/manage-server-data/adopt-rtk-query/references/endpoint-lifecycle.md +36 -0
  68. package/skills/model-redux-state/build-slices-and-selectors/SKILL.md +364 -0
  69. package/skills/model-redux-state/build-slices-and-selectors/references/slice-patterns.md +59 -0
  70. package/skills/model-redux-state/design-state-ownership/SKILL.md +322 -0
  71. package/skills/model-redux-state/design-state-ownership/references/state-ownership.md +28 -0
  72. package/skills/orchestrate-side-effects/handle-side-effects/SKILL.md +271 -0
  73. package/skills/orchestrate-side-effects/handle-side-effects/references/listener-workflows.md +34 -0
  74. package/src/actionCreatorInvariantMiddleware.ts +34 -0
  75. package/src/autoBatchEnhancer.ts +146 -0
  76. package/src/combineSlices.ts +487 -0
  77. package/src/configureStore.ts +248 -0
  78. package/src/createAction.ts +324 -0
  79. package/src/createAsyncThunk.ts +791 -0
  80. package/src/createDraftSafeSelector.ts +30 -0
  81. package/src/createReducer.ts +217 -0
  82. package/src/createSlice.ts +1079 -0
  83. package/src/devtoolsExtension.ts +241 -0
  84. package/src/dynamicMiddleware/index.ts +93 -0
  85. package/src/dynamicMiddleware/react/index.ts +101 -0
  86. package/src/dynamicMiddleware/types.ts +82 -0
  87. package/src/entities/create_adapter.ts +47 -0
  88. package/src/entities/entity_state.ts +38 -0
  89. package/src/entities/index.ts +8 -0
  90. package/src/entities/models.ts +198 -0
  91. package/src/entities/sorted_state_adapter.ts +266 -0
  92. package/src/entities/state_adapter.ts +58 -0
  93. package/src/entities/state_selectors.ts +73 -0
  94. package/src/entities/unsorted_state_adapter.ts +204 -0
  95. package/src/entities/utils.ts +68 -0
  96. package/src/formatProdErrorMessage.ts +13 -0
  97. package/src/getDefaultEnhancers.ts +31 -0
  98. package/src/getDefaultMiddleware.ts +113 -0
  99. package/src/immerImports.ts +7 -0
  100. package/src/immutableStateInvariantMiddleware.ts +274 -0
  101. package/src/index.ts +213 -0
  102. package/src/listenerMiddleware/exceptions.ts +20 -0
  103. package/src/listenerMiddleware/index.ts +562 -0
  104. package/src/listenerMiddleware/task.ts +100 -0
  105. package/src/listenerMiddleware/types.ts +886 -0
  106. package/src/listenerMiddleware/utils.ts +30 -0
  107. package/src/mapBuilders.ts +298 -0
  108. package/src/matchers.ts +365 -0
  109. package/src/nanoid.ts +20 -0
  110. package/src/query/HandledError.ts +6 -0
  111. package/src/query/apiTypes.ts +120 -0
  112. package/src/query/baseQueryTypes.ts +101 -0
  113. package/src/query/core/apiState.ts +377 -0
  114. package/src/query/core/buildInitiate.ts +596 -0
  115. package/src/query/core/buildMiddleware/batchActions.ts +207 -0
  116. package/src/query/core/buildMiddleware/cacheCollection.ts +204 -0
  117. package/src/query/core/buildMiddleware/cacheLifecycle.ts +379 -0
  118. package/src/query/core/buildMiddleware/devMiddleware.ts +34 -0
  119. package/src/query/core/buildMiddleware/index.ts +162 -0
  120. package/src/query/core/buildMiddleware/invalidationByTags.ts +139 -0
  121. package/src/query/core/buildMiddleware/polling.ts +187 -0
  122. package/src/query/core/buildMiddleware/queryLifecycle.ts +508 -0
  123. package/src/query/core/buildMiddleware/types.ts +173 -0
  124. package/src/query/core/buildMiddleware/windowEventHandling.ts +64 -0
  125. package/src/query/core/buildSelectors.ts +413 -0
  126. package/src/query/core/buildSlice.ts +735 -0
  127. package/src/query/core/buildThunks.ts +1124 -0
  128. package/src/query/core/index.ts +58 -0
  129. package/src/query/core/module.ts +727 -0
  130. package/src/query/core/rtkImports.ts +24 -0
  131. package/src/query/core/setupListeners.ts +118 -0
  132. package/src/query/createApi.ts +506 -0
  133. package/src/query/defaultSerializeQueryArgs.ts +52 -0
  134. package/src/query/endpointDefinitions.ts +1717 -0
  135. package/src/query/fakeBaseQuery.ts +21 -0
  136. package/src/query/fetchBaseQuery.ts +385 -0
  137. package/src/query/index.ts +105 -0
  138. package/src/query/react/ApiProvider.tsx +69 -0
  139. package/src/query/react/buildHooks.ts +2297 -0
  140. package/src/query/react/constants.ts +2 -0
  141. package/src/query/react/index.ts +45 -0
  142. package/src/query/react/module.ts +275 -0
  143. package/src/query/react/namedHooks.ts +59 -0
  144. package/src/query/react/reactImports.ts +10 -0
  145. package/src/query/react/reactReduxImports.ts +1 -0
  146. package/src/query/react/rtkqImports.ts +8 -0
  147. package/src/query/react/useSerializedStableValue.ts +17 -0
  148. package/src/query/react/useShallowStableValue.ts +13 -0
  149. package/src/query/retry.ts +233 -0
  150. package/src/query/standardSchema.ts +35 -0
  151. package/src/query/tsHelpers.ts +48 -0
  152. package/src/query/utils/capitalize.ts +3 -0
  153. package/src/query/utils/copyWithStructuralSharing.ts +27 -0
  154. package/src/query/utils/countObjectKeys.ts +14 -0
  155. package/src/query/utils/filterMap.ts +27 -0
  156. package/src/query/utils/getCurrent.ts +6 -0
  157. package/src/query/utils/getOrInsert.ts +41 -0
  158. package/src/query/utils/immerImports.ts +9 -0
  159. package/src/query/utils/index.ts +11 -0
  160. package/src/query/utils/isAbsoluteUrl.ts +9 -0
  161. package/src/query/utils/isDocumentVisible.ts +12 -0
  162. package/src/query/utils/isNotNullish.ts +7 -0
  163. package/src/query/utils/isOnline.ts +12 -0
  164. package/src/query/utils/isValidUrl.ts +9 -0
  165. package/src/query/utils/joinUrls.ts +26 -0
  166. package/src/query/utils/signals.ts +33 -0
  167. package/src/react/index.ts +7 -0
  168. package/src/reduxImports.ts +8 -0
  169. package/src/reselectImports.ts +1 -0
  170. package/src/serializableStateInvariantMiddleware.ts +285 -0
  171. package/src/tsHelpers.ts +214 -0
  172. package/src/uncheckedindexed.ts +16 -0
  173. package/src/utils.ts +125 -0
@@ -0,0 +1,364 @@
1
+ ---
2
+ name: model-redux-state/build-slices-and-selectors
3
+ description: >
4
+ Use this when authoring or refactoring slices with createSlice, selectors,
5
+ create.asyncThunk, entity adapters, or lazy reducer injection. Covers
6
+ Immer-backed mutation syntax, slice selectors, getSelectors, injectInto,
7
+ withLazyLoadedSlices, and current RTK 2 slice patterns.
8
+ type: core
9
+ library: "@reduxjs/toolkit"
10
+ library_version: "2.11.2"
11
+ requires:
12
+ - model-redux-state/design-state-ownership
13
+ sources:
14
+ - "reduxjs/redux-toolkit:docs/api/createSlice.mdx"
15
+ - "reduxjs/redux-toolkit:docs/api/combineSlices.mdx"
16
+ - "reduxjs/redux-toolkit:docs/api/createEntityAdapter.mdx"
17
+ - "reduxjs/redux-toolkit:docs/usage/immer-reducers.md"
18
+ - "reduxjs/redux-toolkit:docs/usage/migrating-rtk-2.md"
19
+ - "reduxjs/redux:docs/style-guide/style-guide.md"
20
+ ---
21
+
22
+ # Build Slices And Selectors
23
+
24
+ ## Setup
25
+
26
+ ```ts
27
+ // file: src/app/createAppSlice.ts
28
+ import { asyncThunkCreator, buildCreateSlice } from '@reduxjs/toolkit'
29
+
30
+ export const createAppSlice = buildCreateSlice({
31
+ creators: { asyncThunk: asyncThunkCreator },
32
+ })
33
+
34
+ // file: src/features/posts/postsSlice.ts
35
+ import { createSelector } from '@reduxjs/toolkit'
36
+ import { createAppSlice } from '../../app/createAppSlice'
37
+
38
+ type PostsState = {
39
+ items: { id: string; title: string; published: boolean }[]
40
+ status: 'idle' | 'pending' | 'succeeded' | 'failed'
41
+ }
42
+
43
+ const initialState: PostsState = {
44
+ items: [],
45
+ status: 'idle',
46
+ }
47
+
48
+ export const postsSlice = createAppSlice({
49
+ name: 'posts',
50
+ initialState,
51
+ reducers: (create) => ({
52
+ postAdded: create.reducer<{ id: string; title: string }>((state, action) => {
53
+ state.items.push({ ...action.payload, published: false })
54
+ }),
55
+ fetchPosts: create.asyncThunk(
56
+ async () => {
57
+ const response = await fetch('/api/posts')
58
+ return (await response.json()) as { id: string; title: string; published: boolean }[]
59
+ },
60
+ {
61
+ pending: (state) => {
62
+ state.status = 'pending'
63
+ },
64
+ fulfilled: (state, action) => {
65
+ state.status = 'succeeded'
66
+ state.items = action.payload
67
+ },
68
+ rejected: (state) => {
69
+ state.status = 'failed'
70
+ },
71
+ },
72
+ ),
73
+ }),
74
+ selectors: {
75
+ selectPosts: (state) => state.items,
76
+ selectPublishedPosts: createSelector(
77
+ [(state: PostsState) => state.items],
78
+ (items) => items.filter((post) => post.published),
79
+ ),
80
+ },
81
+ })
82
+
83
+ export const { postAdded, fetchPosts } = postsSlice.actions
84
+ export const { selectPosts, selectPublishedPosts } = postsSlice.selectors
85
+ ```
86
+
87
+ ## Core Patterns
88
+
89
+ ### Use mutating logic inside slice reducers
90
+
91
+ ```ts
92
+ import { createSlice } from '@reduxjs/toolkit'
93
+
94
+ const todosSlice = createSlice({
95
+ name: 'todos',
96
+ initialState: [] as { id: string; text: string; done: boolean }[],
97
+ reducers: {
98
+ todoAdded(state, action: { payload: { id: string; text: string } }) {
99
+ state.push({ ...action.payload, done: false })
100
+ },
101
+ todoToggled(state, action: { payload: { id: string } }) {
102
+ const todo = state.find((item) => item.id === action.payload.id)
103
+ if (todo) {
104
+ todo.done = !todo.done
105
+ }
106
+ },
107
+ },
108
+ })
109
+ ```
110
+
111
+ Immer is the default inside `createSlice`; write the reducer logic directly instead of copying arrays and objects by hand.
112
+
113
+ ### Define selectors in the slice when they belong to the slice
114
+
115
+ ```ts
116
+ import { createSlice } from '@reduxjs/toolkit'
117
+
118
+ const counterSlice = createSlice({
119
+ name: 'counter',
120
+ initialState: { value: 0 },
121
+ reducers: {
122
+ increment(state) {
123
+ state.value += 1
124
+ },
125
+ },
126
+ selectors: {
127
+ selectValue: (state) => state.value,
128
+ selectIsPositive: (state) => state.value > 0,
129
+ },
130
+ })
131
+
132
+ const { selectValue, selectIsPositive } = counterSlice.selectors
133
+ ```
134
+
135
+ Slice selectors keep state-location knowledge next to the slice.
136
+
137
+ ### Use `create.asyncThunk` when the async lifecycle belongs to the slice
138
+
139
+ ```ts
140
+ import { asyncThunkCreator, buildCreateSlice } from '@reduxjs/toolkit'
141
+
142
+ const createAppSlice = buildCreateSlice({
143
+ creators: { asyncThunk: asyncThunkCreator },
144
+ })
145
+
146
+ const usersSlice = createAppSlice({
147
+ name: 'users',
148
+ initialState: { items: [] as { id: string; name: string }[], status: 'idle' as 'idle' | 'pending' | 'failed' },
149
+ reducers: (create) => ({
150
+ fetchUsers: create.asyncThunk(
151
+ async () => {
152
+ const response = await fetch('/api/users')
153
+ return (await response.json()) as { id: string; name: string }[]
154
+ },
155
+ {
156
+ pending: (state) => {
157
+ state.status = 'pending'
158
+ },
159
+ fulfilled: (state, action) => {
160
+ state.status = 'idle'
161
+ state.items = action.payload
162
+ },
163
+ rejected: (state) => {
164
+ state.status = 'failed'
165
+ },
166
+ },
167
+ ),
168
+ }),
169
+ })
170
+ ```
171
+
172
+ Use this when the async lifecycle handlers naturally live with the slice; otherwise regular `createAsyncThunk` is still fine.
173
+
174
+ ### Use entity adapters and lazy injection for scalable slices
175
+
176
+ ```ts
177
+ import {
178
+ combineSlices,
179
+ createEntityAdapter,
180
+ createSlice,
181
+ } from '@reduxjs/toolkit'
182
+
183
+ type Book = { bookId: string; title: string }
184
+
185
+ const booksAdapter = createEntityAdapter<Book>({
186
+ selectId: (book) => book.bookId,
187
+ })
188
+
189
+ const booksSlice = createSlice({
190
+ name: 'books',
191
+ initialState: booksAdapter.getInitialState(),
192
+ reducers: {
193
+ booksReceived: booksAdapter.setAll,
194
+ },
195
+ })
196
+
197
+ export interface LazyLoadedSlices {}
198
+
199
+ export const rootReducer =
200
+ combineSlices().withLazyLoadedSlices<LazyLoadedSlices>()
201
+
202
+ declare module './rootReducer' {
203
+ export interface LazyLoadedSlices {}
204
+ }
205
+
206
+ const injectedBooksSlice = booksSlice.injectInto(rootReducer)
207
+
208
+ const selectors = booksAdapter.getSelectors(
209
+ (state: ReturnType<typeof rootReducer.selector.original>) =>
210
+ injectedBooksSlice.selectSlice(state),
211
+ )
212
+ ```
213
+
214
+ Entity adapters standardize normalized collections, and `injectInto` lets a slice stay aware of its injected location.
215
+
216
+ ## Common Mistakes
217
+
218
+ ### CRITICAL Using mutating logic outside slice reducers
219
+
220
+ Wrong:
221
+
222
+ ```ts
223
+ type Todo = { id: string; text: string }
224
+
225
+ export function addTodo(todos: Todo[], todo: Todo) {
226
+ todos.push(todo)
227
+ return todos
228
+ }
229
+ ```
230
+
231
+ Correct:
232
+
233
+ ```ts
234
+ type Todo = { id: string; text: string }
235
+
236
+ const todosSlice = createSlice({
237
+ name: 'todos',
238
+ initialState: [] as Todo[],
239
+ reducers: {
240
+ todoAdded(state, action: { payload: Todo }) {
241
+ state.push(action.payload)
242
+ },
243
+ },
244
+ })
245
+ ```
246
+
247
+ Mutation syntax is only safe inside Immer-backed reducer contexts such as `createSlice` and `createReducer`.
248
+
249
+ Source: reduxjs/redux-toolkit:docs/usage/immer-reducers.md
250
+
251
+ ### HIGH Writing hand-written switch reducers as the default
252
+
253
+ Wrong:
254
+
255
+ ```ts
256
+ export default function todosReducer(state = initialState, action: { type: string; payload?: Todo }) {
257
+ switch (action.type) {
258
+ case 'todos/todoAdded':
259
+ return state.concat(action.payload as Todo)
260
+ default:
261
+ return state
262
+ }
263
+ }
264
+ ```
265
+
266
+ Correct:
267
+
268
+ ```ts
269
+ const todosSlice = createSlice({
270
+ name: 'todos',
271
+ initialState,
272
+ reducers: {
273
+ todoAdded(state, action: { payload: Todo }) {
274
+ state.push(action.payload)
275
+ },
276
+ },
277
+ })
278
+ ```
279
+
280
+ Hand-written reducers are an escape hatch for proven bottlenecks, not the normal thing an agent should generate in RTK code.
281
+
282
+ Source: reduxjs/redux-toolkit:docs/usage/migrating-to-modern-redux.mdx
283
+
284
+ ### HIGH Writing RTK 1.x object syntax for `extraReducers`
285
+
286
+ Wrong:
287
+
288
+ ```ts
289
+ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
290
+
291
+ const initialState = { items: [] as { id: string; title: string }[] }
292
+
293
+ const fetchPosts = createAsyncThunk('posts/fetch', async () => {
294
+ const response = await fetch('/api/posts')
295
+ return (await response.json()) as { id: string; title: string }[]
296
+ })
297
+
298
+ const postsSlice = createSlice({
299
+ name: 'posts',
300
+ initialState,
301
+ reducers: {},
302
+ extraReducers: {
303
+ [fetchPosts.fulfilled.type]: (state, action) => {
304
+ state.items = action.payload
305
+ },
306
+ },
307
+ })
308
+ ```
309
+
310
+ Correct:
311
+
312
+ ```ts
313
+ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
314
+
315
+ const initialState = { items: [] as { id: string; title: string }[] }
316
+
317
+ const fetchPosts = createAsyncThunk('posts/fetch', async () => {
318
+ const response = await fetch('/api/posts')
319
+ return (await response.json()) as { id: string; title: string }[]
320
+ })
321
+
322
+ const postsSlice = createSlice({
323
+ name: 'posts',
324
+ initialState,
325
+ reducers: {},
326
+ extraReducers: (builder) => {
327
+ builder.addCase(fetchPosts.fulfilled, (state, action) => {
328
+ state.items = action.payload
329
+ })
330
+ },
331
+ })
332
+ ```
333
+
334
+ RTK 2 removed the object form; agents trained on RTK 1.x still generate it.
335
+
336
+ Source: reduxjs/redux-toolkit:docs/usage/migrating-rtk-2.md
337
+
338
+ ### HIGH Assuming `entity.id` exists for every collection
339
+
340
+ Wrong:
341
+
342
+ ```ts
343
+ type Book = { bookId: string; title: string }
344
+
345
+ const booksAdapter = createEntityAdapter<Book>()
346
+ ```
347
+
348
+ Correct:
349
+
350
+ ```ts
351
+ type Book = { bookId: string; title: string }
352
+
353
+ const booksAdapter = createEntityAdapter<Book>({
354
+ selectId: (book) => book.bookId,
355
+ })
356
+ ```
357
+
358
+ Adapters default to `entity.id`; collections keyed by another field must provide `selectId`.
359
+
360
+ Source: reduxjs/redux-toolkit:docs/api/createEntityAdapter.mdx
361
+
362
+ ## References
363
+
364
+ - [Slice selectors, async creators, and lazy injection details](references/slice-patterns.md)
@@ -0,0 +1,59 @@
1
+ # Slice Patterns
2
+
3
+ ## `getSelectors` for alternate mounting points
4
+
5
+ ```ts
6
+ const counterSlice = createSlice({
7
+ name: 'counter',
8
+ initialState: { value: 0 },
9
+ reducers: {},
10
+ selectors: {
11
+ selectValue: (state) => state.value,
12
+ },
13
+ })
14
+
15
+ export const { selectValue } = counterSlice.getSelectors(
16
+ (state: { customCounter: { value: number } }) => state.customCounter,
17
+ )
18
+ ```
19
+
20
+ Use `getSelectors` when the slice is not mounted at its default `reducerPath`.
21
+
22
+ ## `withLazyLoadedSlices` and `injectInto`
23
+
24
+ ```ts
25
+ import { combineSlices, createSlice, type WithSlice } from '@reduxjs/toolkit'
26
+
27
+ const staticSlice = createSlice({
28
+ name: 'static',
29
+ initialState: { ready: true },
30
+ reducers: {},
31
+ })
32
+
33
+ export interface LazyLoadedSlices {}
34
+
35
+ export const rootReducer =
36
+ combineSlices(staticSlice).withLazyLoadedSlices<LazyLoadedSlices>()
37
+
38
+ const lazySlice = createSlice({
39
+ name: 'lazy',
40
+ initialState: { value: 0 },
41
+ reducers: {
42
+ increment(state) {
43
+ state.value += 1
44
+ },
45
+ },
46
+ })
47
+
48
+ declare module '../rootReducer' {
49
+ export interface LazyLoadedSlices extends WithSlice<typeof lazySlice> {}
50
+ }
51
+
52
+ export const injectedLazySlice = lazySlice.injectInto(rootReducer)
53
+ ```
54
+
55
+ This keeps RootState types aware of reducers that will be injected later.
56
+
57
+ ## Selector caveat
58
+
59
+ If a selector depends on caller-specific arguments and must be memoized per caller, prefer a selector factory outside `createSlice.selectors`. `createSlice.selectors` gives you one selector instance, not a selector factory.