Skip to content

Commit 5403d80

Browse files
committed
remove first argument for exposeAction and exposeCaseReducer, and always use reducerName
1 parent 94937b1 commit 5403d80

File tree

5 files changed

+98
-85
lines changed

5 files changed

+98
-85
lines changed

docs/usage/custom-slice-creators.mdx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -400,13 +400,13 @@ const reducerCreator: ReducerCreator<typeof reducerCreatorType> = {
400400
reducer,
401401
}
402402
},
403-
handle({ reducerName, type }, definition, context) {
403+
handle({ type }, definition, context) {
404404
const { reducer } = definition
405405
const actionCreator = createAction(type)
406406
context
407407
.addCase(actionCreator, reducer)
408-
.exposeAction(reducerName, actionCreator)
409-
.exposeCaseReducer(reducerName, reducer)
408+
.exposeAction(actionCreator)
409+
.exposeCaseReducer(reducer)
410410
},
411411
}
412412
```
@@ -456,19 +456,19 @@ context.addMatcher(matcher, reducer)
456456

457457
#### `exposeAction`
458458

459-
Attaches a value to `slice.actions`. Receives the key to be set under (typically `reducerName`) and the value to be set.
459+
Attaches a value to `slice.actions[reducerName]`.
460460

461461
```ts no-transpile
462462
const action = createAction(type)
463-
context.exposeAction(reducerName, action)
463+
context.exposeAction(action)
464464
```
465465

466466
#### `exposeCaseReducer`
467467

468-
Attaches a value to `slice.caseReducers`. Receives the key to be set under (typically `reducerName`) and the value to be set.
468+
Attaches a value to `slice.caseReducers[reducerName]`.
469469

470470
```ts no-transpile
471-
context.exposeCaseReducer(reducerName, reducer)
471+
context.exposeCaseReducer(reducer)
472472
```
473473

474474
#### `getInitialState`
@@ -480,8 +480,8 @@ const resetAction = createAction(type)
480480
const resetReducer = () => context.getInitialState()
481481
context
482482
.addCase(resetAction, resetReducer)
483-
.exposeAction(reducerName, resetAction)
484-
.exposeCaseReducer(reducerName, resetReducer)
483+
.exposeAction(resetAction)
484+
.exposeCaseReducer(resetReducer)
485485
```
486486

487487
### Typescript
@@ -820,7 +820,7 @@ const toastCreator: ReducerCreator<typeof toastCreatorType> = {
820820
}
821821
},
822822
// handle the reducer definition
823-
handle({ reducerName, type }, definition, context) {
823+
handle({ type }, definition, context) {
824824
// make the action creators
825825
const shown = createAction(type + '/shown', (toast: Toast, id: string) => ({
826826
payload: toast,
@@ -859,12 +859,10 @@ const toastCreator: ReducerCreator<typeof toastCreatorType> = {
859859
}
860860

861861
// expose the thunk creator as `slice.actions[reducerName]` and the case reducers as `slice.caseReducers[reducerName]["shown" | "hidden"]`
862-
context
863-
.exposeAction(reducerName, thunkCreator)
864-
.exposeCaseReducer(reducerName, {
865-
shown: definition.shown || noop,
866-
hidden: definition.hidden || noop,
867-
})
862+
context.exposeAction(thunkCreator).exposeCaseReducer({
863+
shown: definition.shown || noop,
864+
hidden: definition.hidden || noop,
865+
})
868866
},
869867
}
870868

packages/toolkit/src/asyncThunkCreator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ export const asyncThunkCreator: ReducerCreator<ReducerType.asyncThunk> = {
125125
asyncThunk.withTypes = () => asyncThunk
126126
return asyncThunk as AsyncThunkCreator<any>
127127
})(),
128-
handle({ type, reducerName }, definition, context) {
128+
handle({ type }, definition, context) {
129129
const { payloadCreator, fulfilled, pending, rejected, settled, options } =
130130
definition
131131
const thunk = createAsyncThunk(type, payloadCreator, options as any)
132-
context.exposeAction(reducerName, thunk)
132+
context.exposeAction(thunk)
133133

134134
if (fulfilled) {
135135
context.addCase(thunk.fulfilled, fulfilled)
@@ -144,7 +144,7 @@ export const asyncThunkCreator: ReducerCreator<ReducerType.asyncThunk> = {
144144
context.addMatcher(thunk.settled, settled)
145145
}
146146

147-
context.exposeCaseReducer(reducerName, {
147+
context.exposeCaseReducer({
148148
fulfilled: fulfilled || noop,
149149
pending: pending || noop,
150150
rejected: rejected || noop,

packages/toolkit/src/createSlice.ts

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -226,35 +226,27 @@ export interface ReducerHandlingContext<State> {
226226
reducer: CaseReducer<State, A extends Action ? A : A & Action>,
227227
): ReducerHandlingContext<State>
228228
/**
229-
* Add an action to be exposed under the final `slice.actions` key.
230-
* @param name The key to be exposed as.
229+
* Add an action to be exposed under the final `slice.actions[reducerName]` key.
231230
* @param actionCreator The action to expose.
232231
* @example
233-
* context.exposeAction("addPost", createAction<Post>("addPost"));
232+
* context.exposeAction(createAction<Post>(type));
234233
*
235234
* export const { addPost } = slice.actions
236235
*
237236
* dispatch(addPost(post))
238237
*/
239-
exposeAction(
240-
name: string,
241-
actionCreator: unknown,
242-
): ReducerHandlingContext<State>
238+
exposeAction(actionCreator: unknown): ReducerHandlingContext<State>
243239
/**
244-
* Add a case reducer to be exposed under the final `slice.caseReducers` key.
245-
* @param name The key to be exposed as.
240+
* Add a case reducer to be exposed under the final `slice.caseReducers[reducerName]` key.
246241
* @param reducer The reducer to expose.
247242
* @example
248-
* context.exposeCaseReducer("addPost", (state, action: PayloadAction<Post>) => {
243+
* context.exposeCaseReducer((state, action: PayloadAction<Post>) => {
249244
* state.push(action.payload)
250245
* })
251246
*
252247
* slice.caseReducers.addPost([], addPost(post))
253248
*/
254-
exposeCaseReducer(
255-
name: string,
256-
reducer: unknown,
257-
): ReducerHandlingContext<State>
249+
exposeCaseReducer(reducer: unknown): ReducerHandlingContext<State>
258250
/**
259251
* Provides access to the initial state value given to the slice.
260252
* If a lazy state initializer was provided, it will be called and a fresh value returned.
@@ -756,11 +748,11 @@ export const reducerCreator: ReducerCreator<ReducerType.reducer> = {
756748
} as const,
757749
)
758750
},
759-
handle({ type, reducerName }, reducer, context) {
751+
handle({ type }, reducer, context) {
760752
context
761753
.addCase(type, reducer as any)
762-
.exposeCaseReducer(reducerName, reducer)
763-
.exposeAction(reducerName, createAction(type))
754+
.exposeCaseReducer(reducer)
755+
.exposeAction(createAction(type))
764756
},
765757
}
766758

@@ -774,11 +766,11 @@ export const preparedReducerCreator: ReducerCreator<ReducerType.reducerWithPrepa
774766
reducer,
775767
}
776768
},
777-
handle({ type, reducerName }, { prepare, reducer }, context) {
769+
handle({ type }, { prepare, reducer }, context) {
778770
context
779771
.addCase(type, reducer)
780-
.exposeCaseReducer(reducerName, reducer)
781-
.exposeAction(reducerName, createAction(type, prepare))
772+
.exposeCaseReducer(reducer)
773+
.exposeAction(createAction(type, prepare))
782774
},
783775
}
784776

@@ -892,49 +884,64 @@ export function buildCreateSlice<
892884

893885
const getInitialState = makeGetInitialState(options.initialState)
894886

895-
const context: InternalReducerHandlingContext<State> = {
887+
const internalContext: InternalReducerHandlingContext<State> = {
896888
sliceCaseReducersByName: {},
897889
sliceCaseReducersByType: {},
898890
actionCreators: {},
899891
sliceMatchers: [],
900892
}
901893

902-
const contextMethods: ReducerHandlingContext<State> = {
903-
addCase(
904-
typeOrActionCreator: string | TypedActionCreator<any>,
905-
reducer: CaseReducer<State>,
906-
) {
907-
const type =
908-
typeof typeOrActionCreator === 'string'
909-
? typeOrActionCreator
910-
: typeOrActionCreator.type
911-
if (!type) {
912-
throw new Error(
913-
'`context.addCase` cannot be called with an empty action type',
914-
)
915-
}
916-
if (type in context.sliceCaseReducersByType) {
917-
throw new Error(
918-
'`context.addCase` cannot be called with two reducers for the same action type: ' +
919-
type,
920-
)
921-
}
922-
context.sliceCaseReducersByType[type] = reducer
923-
return contextMethods
924-
},
925-
addMatcher(matcher, reducer) {
926-
context.sliceMatchers.push({ matcher, reducer })
927-
return contextMethods
928-
},
929-
exposeAction(name, actionCreator) {
930-
context.actionCreators[name] = actionCreator
931-
return contextMethods
932-
},
933-
exposeCaseReducer(name, reducer) {
934-
context.sliceCaseReducersByName[name] = reducer
935-
return contextMethods
936-
},
937-
getInitialState,
894+
function getContext({ reducerName }: ReducerDetails) {
895+
const context: ReducerHandlingContext<State> = {
896+
addCase(
897+
typeOrActionCreator: string | TypedActionCreator<any>,
898+
reducer: CaseReducer<State>,
899+
) {
900+
const type =
901+
typeof typeOrActionCreator === 'string'
902+
? typeOrActionCreator
903+
: typeOrActionCreator.type
904+
if (!type) {
905+
throw new Error(
906+
'`context.addCase` cannot be called with an empty action type',
907+
)
908+
}
909+
if (type in internalContext.sliceCaseReducersByType) {
910+
throw new Error(
911+
'`context.addCase` cannot be called with two reducers for the same action type: ' +
912+
type,
913+
)
914+
}
915+
internalContext.sliceCaseReducersByType[type] = reducer
916+
return context
917+
},
918+
addMatcher(matcher, reducer) {
919+
internalContext.sliceMatchers.push({ matcher, reducer })
920+
return context
921+
},
922+
exposeAction(actionCreator) {
923+
if (reducerName in internalContext.actionCreators) {
924+
throw new Error(
925+
'context.exposeAction cannot be called twice for the same reducer definition:' +
926+
reducerName,
927+
)
928+
}
929+
internalContext.actionCreators[reducerName] = actionCreator
930+
return context
931+
},
932+
exposeCaseReducer(reducer) {
933+
if (reducerName in internalContext.sliceCaseReducersByName) {
934+
throw new Error(
935+
'context.exposeCaseReducer cannot be called twice for the same reducer definition:' +
936+
reducerName,
937+
)
938+
}
939+
internalContext.sliceCaseReducersByName[reducerName] = reducer
940+
return context
941+
},
942+
getInitialState,
943+
}
944+
return context
938945
}
939946

940947
if (isCreatorCallback(options.reducers)) {
@@ -955,7 +962,11 @@ export function buildCreateSlice<
955962
reducerName,
956963
type: getType(name, reducerName),
957964
}
958-
handler(reducerDetails, reducerDefinition as any, contextMethods)
965+
handler(
966+
reducerDetails,
967+
reducerDefinition as any,
968+
getContext(reducerDetails),
969+
)
959970
}
960971
} else {
961972
for (const [reducerName, reducerDefinition] of Object.entries(
@@ -970,7 +981,11 @@ export function buildCreateSlice<
970981
'reducer' in reducerDefinition
971982
? preparedReducerCreator
972983
: reducerCreator
973-
handler.handle(reducerDetails, reducerDefinition as any, contextMethods)
984+
handler.handle(
985+
reducerDetails,
986+
reducerDefinition as any,
987+
getContext(reducerDetails),
988+
)
974989
}
975990
}
976991

@@ -993,14 +1008,14 @@ export function buildCreateSlice<
9931008

9941009
const finalCaseReducers = {
9951010
...extraReducers,
996-
...context.sliceCaseReducersByType,
1011+
...internalContext.sliceCaseReducersByType,
9971012
}
9981013

9991014
return createReducer(options.initialState, (builder) => {
10001015
for (let key in finalCaseReducers) {
10011016
builder.addCase(key, finalCaseReducers[key] as CaseReducer)
10021017
}
1003-
for (let sM of context.sliceMatchers) {
1018+
for (let sM of internalContext.sliceMatchers) {
10041019
builder.addMatcher(sM.matcher, sM.reducer)
10051020
}
10061021
for (let m of actionMatchers) {
@@ -1101,8 +1116,8 @@ export function buildCreateSlice<
11011116
> = {
11021117
name,
11031118
reducer,
1104-
actions: context.actionCreators as any,
1105-
caseReducers: context.sliceCaseReducersByName as any,
1119+
actions: internalContext.actionCreators as any,
1120+
caseReducers: internalContext.sliceCaseReducersByName as any,
11061121
getInitialState,
11071122
...makeSelectorProps(reducerPath),
11081123
injectInto(injectable, { reducerPath: pathOpt, ...config } = {}) {

packages/toolkit/src/tests/createSlice.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ describe('type tests', () => {
821821
.addCase(toastClosed, (state, action) => {
822822
delete state.toasts[action.payload]
823823
})
824-
.exposeAction(reducerName, openToast)
824+
.exposeAction(openToast)
825825
},
826826
}
827827

packages/toolkit/src/tests/createSlice.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,8 @@ describe('createSlice', () => {
730730
if (started) context.addCase(startedAction, started)
731731
if (ended) context.addCase(endedAction, ended)
732732

733-
context.exposeAction(reducerName, thunkCreator)
734-
context.exposeCaseReducer(reducerName, { started, ended })
733+
context.exposeAction(thunkCreator)
734+
context.exposeCaseReducer({ started, ended })
735735
},
736736
}
737737
test('allows passing custom reducer creators, which can add actions and case reducers', () => {

0 commit comments

Comments
 (0)