v2.0.0-alpha.6 #3449
Replies: 3 comments 9 replies
-
I am very excitedly looking forward to the ability to reuse an endpoint within a Example: const api = createApi({
reducerPath: "api",
baseQuery: fetchBaseQuery({
baseUrl: "url",
}),
endpoints: (builder) => {
return {
device: builder.query<Device, string>({
query: (id) => `devices/${id}`, // repeat 1
}),
deployments: builder.query<Deployment[], string>({
queryFn: async (arg, _api, _extraOptions, fetchWithBQ) => {
// I would preferred to call the device endpoint directly.
// It will prevent to repeat the url and get cached data.
const result = await fetchWithBQ(`devices/${arg}`); // repeat 2
return ...
},
}),
};
},
}); |
Beta Was this translation helpful? Give feedback.
-
Hey, since we have to update from Redux to the Redux toolkit, we decided to work on the beta. This is because version 2 might be more compatible and save us from changing things again. While we were surprised to see dynamic reducers now supported, we wondered what had happened to remove middleware. Hopefully, we'll see something similar to |
Beta Was this translation helpful? Give feedback.
-
After update to 2.0.0-alpha.6, my getDefaultMiddleware type issue resolved. |
Beta Was this translation helpful? Give feedback.
-
This is an alpha release for Redux Toolkit 2.0, and has breaking changes. This release updates
createSlice
to allow declaring thunks directly inside thereducers
field using a callback syntax, adds a new "dynamic middleware" middleware, updatesconfigureStore
to add theautoBatchEnhancer
by default, removes the.toString()
override from action creators, updates Reselect from v4.x to v5.0-alpha, updates the Redux core to v5.0-alpha.6, and includes the latest changes from 1.9.x.The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for some of the new features here:
Changelog
Declaring Thunks Inside
createSlice.reducers
One of the oldest feature requests we've had is the ability to declare thunks directly inside of
createSlice
. Until now, you've always had to declare them separately, give the thunk a string action prefix, and handle the actions viacreateSlice.extraReducers
:Many users have told us that this separation feels awkward.
We've wanted to include a way to define thunks directly inside of
createSlice
, and have played around with various prototypes. There were always two major blocking issues, and a secondary concern:1 It wasn't clear what the syntax for declaring a thunk inside should look like.
2. Thunks have access to
getState
anddispatch
, but theRootState
andAppDispatch
types are normally inferred from the store, which in turn infers it from the slice state types. Declaring thunks insidecreateSlice
would cause circular type inference errors, as the store needs the slice types but the slice needs the store types. We weren't willing to ship an API that would work okay for our JS users but not for our TS users, especially since we want people to use TS with RTK.3. You can't do synchronous conditional imports in ES modules, and there's no good way to make the
createAsyncThunk
import optional. EithercreateSlice
always depends on it (and adds that to the bundle size), or it can't usecreateAsyncThunk
at all.We've settled on these compromises:
createSlice.reducers
, by using a "creator callback" syntax for thereducers
field that is similar to thebuild
callback syntax in RTK Query'screateApi
(using typed functions to create fields in an object). Doing this does look a bit different than the existing "object" syntax for thereducers
field, but is still fairly similar.createSlice
, but you cannot customize thestate
ordispatch
types. If those are needed, you can manually do anas
cast, likegetState() as RootState
.createSlice
does now always depend oncreateAsyncThunk
, so thecreateAsyncThunk
implementation will get added to the bundle.In practice, we hope these are reasonable tradeoffs. Creating thunks inside of
createSlice
has been widely asked for, so we think it's an API that will see usage. If the TS customization options are a limitation, you can still declare thunks outside ofcreateSlice
as always, and most async thunks don't needdispatch
orgetState
- they just fetch data and return. And finally,createAsyncThunk
is already being used in many apps, either directly or as part of RTK Query, so in that case there's no additional bundle size increase - you've already paid that cost.Here's what the new callback syntax looks like:
"Dynamic Middleware" Middleware
A Redux store's middleware pipeline is fixed at store creation time and can't be changed later. We have seen ecosystem libraries that tried to allow dynamically adding and removing middleware, potentially useful for things like code splitting.
This is a relatively niche use case, but we've built our own version of a "dynamic middleware" middleware. Add it to the Redux store at setup time, and it lets you add and remove middleware later at runtime. It also comes with a React hook integration that will automatically add a middleware to the store and return the updated
dispatch
method.Store Adds
autoBatchEnhancer
By DefaultIn v1.9.0, we added a new
autoBatchEnhancer
that delays notifying subscribers briefly when multiple "low-priority" actions are dispatched in a row. This improves perf, as UI updates are typically the most expensive part of the update process. RTK Query marks most of its own internal actions as "low-pri" by default, but you have to have theautoBatchEnhancer
added to the store to benefit from that.We've updated
configureStore
to add theautoBatchEnhancer
to the store setup by default, so that users can benefit from the improved perf without needing to manually tweak the store config themselves.configureStore
now also accepts a callback for theenhancers
option that receives agetDefaultEnhancers()
param, equivalent to how themiddleware
callback receivesgetDefaultMiddleware()
:Deprecation Removals
When we first released the early alphas of RTK, one of the main selling points was that you could reuse RTK's action creators as "computed key" fields in the object argument to
createReducer
, like:This was possible because
createAction
overrides thefn.toString()
field on these action creators to return the action type string. When JS sees the function, it implicitly callstodoAdded.toString()
, which returns"todos/todoAdded"
, and that string is used as the key.While this capability was useful early on, it's not useful today. Most users never call
createAction
, becausecreateSlice
automatically generates action creators. Additionally, it has no TS type safety. TS only sees that the key is astring
, and has no idea what the correct TS type foraction
is. We later created the "builder callback" syntax for bothcreateReducer
andcreateSlice.extraReducers
, started teaching that as the default, and removed the "object" argument to both of those in an earlier RTK 2.0 alpha.Because of this, we've now removed the
fn.toString()
override. If you need to access the type string from an action creator function, those still have a.type
field attached:We've also removed the standalone export of
getDefaultMiddleware
, which has been deprecated ever since we added the callback for theconfigureStore.middleware
field that has correct types attached.Finally, we've removed all other fields or type exports that were marked as deprecated in 1.9.x.
Reselect v5 Alpha
We've updated Reselect with the same ESM/CJS package formatting updates as the rest of the Redux libraries.
Reselect v5 alpha now includes a pair of new memoizers:
autotrackMemoize
, which uses signal-style field tracking, andweakmapMemoize
, which has an effectively infinite cache size thanks to use ofWeakMap
s for tracking arguments.We'd appreciate it if users would try out the new memoizers in their apps and give us feedback on their usefulness and any problems or suggestions!
You can use these by creating a customized version of
createSelector
, and RTK now exportscreateSelectorCreator
and all three memoizers:See the Reselect v5 alpha release notes for details on the tradeoffs with each memoizer:
Reselect also now automatically calls each selector twice on first execution in development builds, in order to detect cases where input selectors accidentally return new references too often (which would cause memoization to fail):
This can be configured on a per-selector basis. There's also a global
setInputStabilityCheckEnabled()
override method that is exported from thereselect
package, but is not re-exported from RTK, as we think the check-once behavior is the right default. If you really want to override that globally, addreselect
as an explicit dependency and import the override from there.Redux v2.0-alpha.6
We've updated to Redux core v2.0-alpha.6, which enforces that
action.type
must be a string. In practice this shouldn't affect any of our users - action type strings are mostly an implementation detail now, and RTK uses strings for all actions.TS Minimum Version Updated to 4.7
We've updated all the Redux libraries to requires TS 4.7 as a minimum version. Some of our new types require this anyway, and it also simplifies the maintenance of our type definitions.
What's Changed
Full Changelog: v2.0.0-alpha.5...v2.0.0-alpha.6
This discussion was created from the release v2.0.0-alpha.6.
Beta Was this translation helpful? Give feedback.
All reactions