|
| 1 | +# BuildSlice |
| 2 | + |
| 3 | +## Slices |
| 4 | + |
| 5 | +### querySlice |
| 6 | +#### reducers |
| 7 | + - `removeQueryResult` - delete a specific cacheKey's stored result |
| 8 | + - `queryResultPatched` - patch a specific cacheKey's result |
| 9 | +#### extraReducers - matching queryThunk cases |
| 10 | +- `queryThunk.pending` |
| 11 | + - Initially sets QueryStatus to uninitialized |
| 12 | + - updates QueryStatus to pending |
| 13 | + - Generates requestId |
| 14 | + - stores originalArgs |
| 15 | + - stores startedTimeStamp |
| 16 | +- `queryThunk.fulfilled` |
| 17 | + - handles merge functionality first |
| 18 | + - otherwise updates the cache data, creates a fulfilledTimeStamp and deletes the substates error |
| 19 | + |
| 20 | +```ts no-transpile |
| 21 | +if (merge) { |
| 22 | + if (substate.data !== undefined) { |
| 23 | + const { fulfilledTimeStamp, arg, baseQueryMeta, requestId } = |
| 24 | + meta |
| 25 | + // There's existing cache data. Let the user merge it in themselves. |
| 26 | + // We're already inside an Immer-powered reducer, and the user could just mutate `substate.data` |
| 27 | + // themselves inside of `merge()`. But, they might also want to return a new value. |
| 28 | + // Try to let Immer figure that part out, save the result, and assign it to `substate.data`. |
| 29 | +let newData = createNextState( |
| 30 | + substate.data, |
| 31 | + (draftSubstateData) => { |
| 32 | + // As usual with Immer, you can mutate _or_ return inside here, but not both |
| 33 | + return merge(draftSubstateData, payload, { |
| 34 | + arg: arg.originalArgs, |
| 35 | + baseQueryMeta, |
| 36 | + fulfilledTimeStamp, |
| 37 | + requestId, |
| 38 | + }) |
| 39 | + }, |
| 40 | + ) |
| 41 | + substate.data = newData |
| 42 | + } else { |
| 43 | + // Presumably a fresh request. Just cache the response data. |
| 44 | + substate.data = payload |
| 45 | + } |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +- `queryThunk.rejected` |
| 50 | + - utilises `condition()` from `queryThunk` and does nothing if the rejection is a result of `condition()` (indicates a thunk is already running here) |
| 51 | + - else substate.error is set and the status is changed to rejected |
| 52 | +- `hasRehydrationInfo` |
| 53 | + - iterates through and resets entries for all fulfilled or rejected status |
| 54 | + |
| 55 | +### mutationSlice |
| 56 | +#### reducers |
| 57 | +- `removeMutationResult` |
| 58 | + - calls `getMutationCacheKey` from payload |
| 59 | + - if cacheKey is in draft it deletes `draft[cacheKey`(?) |
| 60 | +#### extraReducers - matching mutationThunk cases |
| 61 | +- `mutationThunk.pending` |
| 62 | + - exits if track is set to false |
| 63 | + - otherwise updates appropriate cacheKey with requestId, pending status and startedTimeStamp |
| 64 | +- `mutationThunk.fulfilled` |
| 65 | + - exits if track is set to false |
| 66 | + - otherwise sets data off payload and fulfilledTimeStamp |
| 67 | +- `mutationThunk.rejected` |
| 68 | + - exits if track is set to false |
| 69 | + - otherwise sets error and status to rejected |
| 70 | +- `hasRehydrationInfo` |
| 71 | + - iterates through and resets entries for all fulfilled or rejected status |
| 72 | + |
| 73 | +### invalidationSlice |
| 74 | + |
| 75 | +#### reducers |
| 76 | +- updateProvidedBy |
| 77 | + - takes queryCacheKey and providedTags from payload |
| 78 | + - appends to a list of idSubscriptions the queryCacheKey that are currently subscribed to for each tag |
| 79 | +#### extraReducers |
| 80 | +- `querySlice.actions.removeQueryResult`, |
| 81 | + - deletes relevant queryCacheKey entry from list of subscription ids |
| 82 | +- `hasRehydrationInfo` |
| 83 | + - TODO |
| 84 | +- `queryThunk.fulfilled` or `queryThunk.rejected` |
| 85 | + - gets list of tags from action and endpoint definition |
| 86 | + - gets queryCacheKey |
| 87 | + - calls updateProvidedBy action |
| 88 | + |
| 89 | +### subscriptionSlice / internalSubscriptionSlice |
| 90 | +#### reducers |
| 91 | +- updateSubscriptionOptions |
| 92 | +- unsubscribeQueryResult |
| 93 | +- internal_getRTKQSubscriptions |
| 94 | +- subscriptionsUpdated |
| 95 | + - applyPatches() to the state from the payload |
| 96 | + |
| 97 | +### configSlice |
| 98 | +#### reducers |
| 99 | +- middlewareRegistered |
| 100 | + - toggles whether the middleware is registered or if there is a conflict |
| 101 | +#### extraReducers |
| 102 | +- `onOnline` |
| 103 | + - manages state.online in response to listenerMiddleware |
| 104 | +- `onOffline` |
| 105 | + - manages state.online in response to listenerMiddleware |
| 106 | +- `onFocus` |
| 107 | + - manages state.focused in response to listenerMiddleware |
| 108 | +- `onFocusLost` |
| 109 | + - manages state.focused in response to listenerMiddleware |
| 110 | +- `hasRehydrationInfo` |
| 111 | + - lists a comment that says: "update the state to be a new object to be picked up as a "state change" by redux-persist's `autoMergeLevel2`" |
| 112 | + |
| 113 | + |
| 114 | +## Functions |
| 115 | +### `updateQuerySubstateIfExists` |
| 116 | +Utility function that takes the api/endpoint state, queryCacheKey and Update function. |
| 117 | +The "SubState" is determined by accessing the `queryCacheKey` value inside the state. If the substate exists, the update function is executed on the substate. |
| 118 | +```js no-transpile |
| 119 | +function updateQuerySubstateIfExists(state, queryCacheKey, update) { |
| 120 | + const substate = state[queryCacheKey]; |
| 121 | + if (substate) { |
| 122 | + update(substate); |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +### `getMutationCacheKey` |
| 128 | +conditionally determines the cachekey to be used for the mutation, prioritising the argument provided, followed by the provided cacheKey, and the generated requestId otherwise |
| 129 | +```ts no-transpile |
| 130 | +export function getMutationCacheKey( |
| 131 | + id: |
| 132 | + | { fixedCacheKey?: string; requestId?: string } |
| 133 | + | MutationSubstateIdentifier |
| 134 | + | { requestId: string; arg: { fixedCacheKey?: string | undefined } }, |
| 135 | +): string | undefined { |
| 136 | + return ('arg' in id ? id.arg.fixedCacheKey : id.fixedCacheKey) ?? id.requestId |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +### `getMutationSubstateIfExists` |
| 141 | + |
| 142 | +same as query version except it uses the id instead of the queryCacheKey, and uses the `getMutationCacheKey` to determine the cachekey |
| 143 | +```js no-transpile |
| 144 | +function updateMutationSubstateIfExists(state, id, update) { |
| 145 | + const substate = state[getMutationCacheKey(id)]; |
| 146 | + if (substate) { |
| 147 | + update(substate); |
| 148 | + } |
| 149 | +} |
| 150 | +``` |
| 151 | + |
0 commit comments