This feature preview release adds new options and improves behavior for RTK Query, adds a runtime deprecation for the "object" form of createReducer/createSlice.extraReducers
, adds the ability to define a "pre-typed" version of createAsyncThunk
, improves TS inference of store enhancers, and exports additional TS types.
We hope to add a couple additional RTKQ options as part of the final 1.9 release, including an upsertQueryData
util. See the RTK 1.9 milestone for remaining items. No hard ETA yet, but ideally we'd like to publish 1.9 within the next couple weeks if we can wrap things up.
Notable Changes
Some highlights for this alpha:
RTKQ merge
Option
RTKQ was built around the assumption that the server is the source of truth, and every refetch replaces the cached data on the client. There are use cases when it would be useful to merge an incoming response into the existing cached data instead, such as pagination or APIs that return varying results over time.
Query endpoints can now accept a merge(cachedData, responseData)
callback that lets you do Immer-powered "mutations" to update the existing cached data instead of replacing it entirely.
Object Reducer Deprecation Warning
RTK's createReducer
API was originally designed to accept a lookup table of action type strings to case reducers, like { "ADD_TODO" : (state, action) => {} }
. We later added the "builder callback" form to allow more flexibility in adding "matchers" and a default handler, and did the same for createSlice.extraReducers
.
We intend to remove the "object" form for both createReducer
and createSlice.extraReducers
in RTK 2.0. The builder callback form is effectively the same number of lines of code, and works much better with TypeScript.
Starting with this release, RTK will print a one-time runtime warning for both createReducer
and createSlice.extraReducers
if you pass in an object argument.
As an example, this:
const todoAdded = createAction('todos/todoAdded');
createReducer(initialState, {
[todoAdded]: (state, action) => {}
})
createSlice({
name,
initialState,
reducers: {/* case reducers here */},
extraReducers: {
[todoAdded]: (state, action) => {}
}
})
should be migrated to:
createReducer(initialState, builder => {
builder.addCase(todoAdded, (state, action) => {})
})
createSlice({
name,
initialState,
reducers: {/* case reducers here */},
extraReducers: builder => {
builder.addCase(todoAdded, (state, action) => {})
}
})
We have initial codemods in the repo that will help rewrite the object form to the builder form, and we'll publish those with instructions alongside 1.9 when it goes final.
RTKQ Internal Improvements
When query hooks mount, they dispatch actions to subscribe to the relevant data. The first hook to do so will dispatch a "subscription/fulfilled" action, and all further hooks asking for the same cache key will dispatch "subscription/rejected" actions. Both cause the reducer logic to add another entry to the subscription tracking.
The dispatching of individual "subscription/rejected" actions was causing perf issues when many components mounted at once, due to the number of extra dispatches. RTKQ now batches those into a single combined action per event loop tick, which improves perf for some many-component use cases noticeably.
TS Types
configureStore
now correctly infers changes to the store shape from any store enhancers.
There's now a createAsyncThunk.withTypes()
method that can be used to create a "pre-typed" version of createAsyncThunk
with types like {state, dispatch, extra}
baked in.
What's Changed
- Add
isJsonContentType
predicate tofetchBaseQuery
by @msutkowski in #2331 - Add
jsonContentType
tofetchBaseQuery
options by @msutkowski in #2403 - Add ThunkMiddleware to the re-exported types from redux-thunk by @orta in #2451
- add timeout option to fetchBaseQuery by @phryneas in #2143
- createSlice: use template literal types for action type by @phryneas in #2250
- add types for manually typing hook results in userland code by @phryneas in #2276
- Add 'content-type' ResponseHandler by @taylorkline in #2363
- feature : endpoint-specific args serializers by @michal-kurz in #2493
- RFC: add "merge" functionality by @phryneas in #1059
- Add runtime deprecation warning for reducer object notation by @markerikson in #2591
- feat: Add the ability to type
StoreEnhancers
by @fostyfost in #2550 - Batch RTKQ "subscribe on reject" actions, and improve cache collection timer handling by @markerikson in #2599
- add transformErrorReponse to rtkq endpoints by @dreyks in #1841
- Fix manually initiate()d rtk-query promises by @wesen in #2187
- Implement codemods for createReducer and createSlice builder by @markerikson in #2602
- RFC: Expose endpoint types by @phryneas in #1646
- add createAsyncThunk.withTypes by @phryneas in #2604
Full Changelog: v1.8.5...v1.9.0-alpha.0