Skip to content

Commit 81d9706

Browse files
authored
Merge pull request #3882 from reduxjs/docs-selectSlice-settled
2 parents cfab6e5 + 82a7c19 commit 81d9706

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

docs/api/createAsyncThunk.mdx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ type RejectedWithValue = <ThunkArg, RejectedValue>(
212212
213213
To handle these actions in your reducers, reference the action creators in `createReducer` or `createSlice` using the "builder callback" notation.
214214
215-
```ts no-transpile {2,6,14,23}
215+
```ts no-transpile {2,10}
216216
const reducer1 = createReducer(initialState, (builder) => {
217217
builder.addCase(fetchUserById.fulfilled, (state, action) => {})
218218
})
@@ -227,6 +227,25 @@ const reducer2 = createSlice({
227227
})
228228
```
229229

230+
Additionally, a `settled` matcher is attached, for matching against both fulfilled and rejected actions. Conceptually this is similar to a `finally` block.
231+
232+
Make sure you use `addMatcher` instead of `addCase`, since `settled` is a matcher rather than an action creator.
233+
234+
```ts no-transpile {2,10}
235+
const reducer1 = createReducer(initialState, (builder) => {
236+
builder.addMatcher(fetchUserById.settled, (state, action) => {})
237+
})
238+
239+
const reducer2 = createSlice({
240+
name: 'users',
241+
initialState,
242+
reducers: {},
243+
extraReducers: (builder) => {
244+
builder.addMatcher(fetchUserById.settled, (state, action) => {})
245+
},
246+
})
247+
```
248+
230249
## Handling Thunk Results
231250

232251
### Unwrapping Result Actions

docs/api/createSlice.mdx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ Then import this `createSlice` as needed instead of the exported version from RT
266266
- **payloadCreator** The thunk [payload creator](./createAsyncThunk#payloadcreator).
267267
- **config** The configuration object. (optional)
268268

269-
The configuration object can contain case reducers for each of the [lifecycle actions](./createAsyncThunk#promise-lifecycle-actions) (`pending`, `fulfilled`, and `rejected`).
269+
The configuration object can contain case reducers for each of the [lifecycle actions](./createAsyncThunk#promise-lifecycle-actions) (`pending`, `fulfilled`, and `rejected`), as well as a `settled` reducer that will run for both fulfilled and rejected actions (note that this will run _after_ any provided `fulfilled`/`rejected` reducers. Conceptually it can be thought of like a `finally` block.).
270270
271271
Each case reducer will be attached to the slice's `caseReducers` object, e.g. `slice.caseReducers.fetchTodo.fulfilled`.
272272
@@ -283,12 +283,14 @@ create.asyncThunk(
283283
state.loading = true
284284
},
285285
rejected: (state, action) => {
286-
state.loading = false
286+
state.error = action.payload ?? action.error
287287
},
288288
fulfilled: (state, action) => {
289-
state.loading = false
290289
state.todos.push(action.payload)
291290
},
291+
settled: (state, action) => {
292+
state.loading = false
293+
}
292294
options: {
293295
idGenerator: uuid,
294296
},
@@ -298,7 +300,7 @@ create.asyncThunk(
298300
299301
:::note
300302
301-
Typing for the `create.asyncThunk` works in the same way as [`createAsyncThunk`](usage/usage-with-typescript#createasyncthunk), with one key difference.
303+
Typing for the `create.asyncThunk` works in the same way as [`createAsyncThunk`](../usage/usage-with-typescript#createasyncthunk), with one key difference.
302304
303305
A type for `state` and/or `dispatch` _cannot_ be provided as part of the `ThunkApiConfig`, as this would cause circular types.
304306

@@ -316,7 +318,7 @@ create.asyncThunk<Todo, string, { rejectValue: { error: string } }>(
316318
)
317319
```
318320

319-
For common thunk API configuration options, a [`withTypes` helper](usage/usage-with-typescript#defining-a-pre-typed-createasyncthunk) is provided:
321+
For common thunk API configuration options, a [`withTypes` helper](../usage/usage-with-typescript#defining-a-pre-typed-createasyncthunk) is provided:
320322

321323
```ts no-transpile
322324
reducers: (create) => {
@@ -451,6 +453,7 @@ const counterSlice = createSlice({
451453
caseReducers: Record<string, CaseReducer>.
452454
getInitialState: () => State,
453455
reducerPath: string,
456+
selectSlice: Selector;
454457
selectors: Record<string, Selector>,
455458
getSelectors: (selectState: (rootState: RootState) => State) => Record<string, Selector>
456459
injectInto: (injectable: Injectable, config?: InjectConfig & { reducerPath?: string }) => InjectedSlice
@@ -488,7 +491,9 @@ As a result, there are two ways of getting final selectors:
488491
489492
Most commonly, the slice is reliably mounted under its [`reducerPath`](#reducerPath).
490493
491-
Following this, the slice has a `selectors` object attached, which creates selectors with the assumption that the slice is located under `rootState[slice.reducerPath]`.
494+
Following this, the slice has a `selectSlice` selector attached, which assumes that the slice is located under `rootState[slice.reducerPath]`.
495+
496+
`slice.selectors` then uses this selector to wrap each of the selectors provided.
492497
493498
```ts
494499
import { createSlice } from '@reduxjs/toolkit'
@@ -508,6 +513,8 @@ const counterSlice = createSlice({
508513
},
509514
})
510515

516+
console.log(counterSlice.selectSlice({ counter: { value: 2 } })) // { value: 2 }
517+
511518
const { selectValue } = counterSlice.selectors
512519

513520
console.log(selectValue({ counter: { value: 2 } })) // 2
@@ -571,8 +578,10 @@ console.log(selectValue({ value: 2 })) // 2
571578
The [`slice.selectors`](#selectors-2) object is the equivalent of calling
572579
573580
```ts no-transpile
581+
const { selectValue } = counterSlice.getSelectors(counterSlice.selectSlice)
582+
// or
574583
const { selectValue } = counterSlice.getSelectors(
575-
(rootState: RootState) => rootState[counterSlice.reducerPath]
584+
(state: RootState) => state[counterSlice.reducerPath]
576585
)
577586
```
578587

0 commit comments

Comments
 (0)