Skip to content

Commit 2c95e3e

Browse files
committed
add cache to combineSlices
1 parent 7c9af65 commit 2c95e3e

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

packages/toolkit/src/combineSlices.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ const stateProxyMap = new WeakMap<object, object>()
323323
const createStateProxy = <State extends object>(
324324
state: State,
325325
reducerMap: Partial<Record<string, Reducer>>,
326+
initialStateCache: Record<string, unknown>,
326327
) =>
327328
getOrInsertComputed(
328329
stateProxyMap,
@@ -332,20 +333,24 @@ const createStateProxy = <State extends object>(
332333
get: (target, prop, receiver) => {
333334
if (prop === ORIGINAL_STATE) return target
334335
const result = Reflect.get(target, prop, receiver)
336+
const propString = prop.toString()
335337
if (typeof result === 'undefined') {
336-
const reducer = reducerMap[prop.toString()]
338+
const cached = initialStateCache[propString]
339+
if (typeof cached !== 'undefined') return cached
340+
const reducer = reducerMap[propString]
337341
if (reducer) {
338342
// ensure action type is random, to prevent reducer treating it differently
339343
const reducerResult = reducer(undefined, { type: nanoid() })
340344
if (typeof reducerResult === 'undefined') {
341345
throw new Error(
342-
`The slice reducer for key "${prop.toString()}" returned undefined when called for selector(). ` +
346+
`The slice reducer for key "${propString}" returned undefined when called for selector(). ` +
343347
`If the state passed to the reducer is undefined, you must ` +
344348
`explicitly return the initial state. The initial state may ` +
345349
`not be undefined. If you don't want to set a value for this reducer, ` +
346350
`you can use null instead of undefined.`,
347351
)
348352
}
353+
initialStateCache[propString] = reducerResult
349354
return reducerResult
350355
}
351356
}
@@ -382,6 +387,8 @@ export function combineSlices<Slices extends Array<AnySliceLike | ReducerMap>>(
382387

383388
combinedReducer.withLazyLoadedSlices = () => combinedReducer
384389

390+
const initialStateCache: Record<string, unknown> = {}
391+
385392
const inject = (
386393
slice: AnySliceLike,
387394
config: InjectConfig = {},
@@ -406,6 +413,10 @@ export function combineSlices<Slices extends Array<AnySliceLike | ReducerMap>>(
406413
return combinedReducer
407414
}
408415

416+
if (config.overrideExisting && currentReducer !== reducerToInject) {
417+
delete initialStateCache[reducerPath]
418+
}
419+
409420
reducerMap[reducerPath] = reducerToInject
410421

411422
reducer = getReducer()
@@ -423,6 +434,7 @@ export function combineSlices<Slices extends Array<AnySliceLike | ReducerMap>>(
423434
createStateProxy(
424435
selectState ? selectState(state as any, ...args) : state,
425436
reducerMap,
437+
initialStateCache,
426438
),
427439
...args,
428440
)

0 commit comments

Comments
 (0)