You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(deps): update dependency @reduxjs/toolkit to v2.13.0 - #856
This feature release updates our build tooling to TSDown and PNPM, adds official TypeScript 7 support, and includes a long list of bugfixes across RTK Query, createAsyncThunk, createEntityAdapter, and combineSlices.
Changelog
Build Tooling Updates
We've fully modernizing modernized our build tooling across all of the Redux repos. That included switching from Yarn to PNPM, ESLint to Oxlint, Prettier to Oxfmt, and TSUp to TSDown.
The part that matters for users is that we now build the package with TSDown instead of tsup. The package layout, exports definitions, and exported APIs are all unchanged from 2.12. We've checked the new build with attw, and verified that CJS and ESM entry points load in both dev and prod builds, and that the legacy-esm artifacts still target ES2017. The contents of the bundles do look a bit different (smaller CJS artifacts, slightly different helper output in the legacy-esm files). If you see any behavior differences that look build-related, please file an issue!
This is also our first release published via the updated PNPM-based workflow, still using NPM Trusted Publishing. We've also added pkg.pr.new previews for every commit, so you can try out a PR build before it's released.
Docs Updates
We've shipped a new combined Redux libraries docs site! The core docs site at https://redux.js.org now contains the docs for all of our libraries: Redux core and usage guides, Redux Toolkit, React Redux, and Reselect. The prior standalone docs sites for RTK, R-R, and Reselect now redirect to their respective sections of the combined docs. We've also done a major cleanup pass on the docs, deduplicating pages that had similarities (like the Next.js or RTK2 migration pages that lived in both the core and RTK docs), and updating outdated content (modernizing example code snippets, deleting dead links, and making RTK and hooks the default patterns shown). The RTK content now lives at https://redux.js.org/toolkit/ .
TypeScript 7 Support
TS 7.0 (the native Go port) is now out! We fixed the remaining type errors in RTK when checked by TS 7.0 and 7.1, and TS 7.0 is now part of our CI test matrix.
Per our TS support policy of matching DefinitelyTyped's support window, we've also updated our support matrix to TS 5.6+. As always, RTK may still work with earlier versions, but we no longer test against them.
RTK Query Fixes
useQueryState (and thus useQuery) was passing a new inline selector to useSelector on every render, and also reading the store directly during render. The selector is now memoized, and the direct store read is gone. This also fixes a bug where isSuccess could flip from false to true on an unrelated re-render while a query was refetching after an error. isSuccess now correctly stays false in that case.
data now reflects cache updates made via updateQueryData while a refetch is in flight, instead of showing the previous result.
Polling now reads the current cache state when each poll fires, rather than the state at the time the poll was scheduled. This means skipPollingIfUnfocused respects focus loss that happens after scheduling, and polls stop if their cache entry was removed.
We fixed a race where a duplicate query request rejected by the thunk condition could cause queued tag invalidations to run too early and be lost, leaving stale data in the cache.
Tags with falsy ids like 0 now invalidate and clean up correctly.
Lazy query hooks now re-subscribe correctly when effects restart while the hook state is preserved, such as with Fast Refresh or <Activity>.
Infinite queries no longer trigger onQueryStarted when fetching past the end of the list, and the infinite query hook result type now includes the page error flags.
fetchBaseQuery only treats a URL as absolute if it starts with a scheme.
We also fixed an error when rehydrating state for an endpoint name that has no definition.
Other Fixes
createAsyncThunk no longer swallows aborts that happen before the pending action is dispatched, and now correctly sets rejectedWithValue when rejectWithValue is called with a falsy payload.
createEntityAdapter's setAll now keeps the last item when given duplicate IDs, matching setMany. The sorted adapter's updateMany now merges multiple updates for the same ID before applying them.
combineSlices now keeps its internal state proxy cache per instance, so multiple combined reducers no longer interfere with each other.
The immutability check middleware now handles circular references in state.
The dynamic middleware now caches its composed middleware chains when the list of middleware hasn't changed.
This feature release adds RTK usage skills files (via TanStack Intent) exports the RTK Query hook options types for reusability, fixes issues with infinite query status flags and batching handling, and makes some small TS improvements.
Changelog
Skills Files
We've generated agent skill files that are now included in the RTK package itself in a skills folder. They cover using and migrating to modern RTK, client and server state management, and handling side effects. You can point your agent at these skills yourself, or use TanStack Intent to pick them up.
TypeScript Improvements
The types for our RTK Query hook options are now exported, which lets you stop using Parameters to extract those types for use in your own code.
The types for listener middleware matchers were tweaked to allow interface-based type guards, not just type-based definitions.
The internal IgnorePaths type was renamed to IgnoredPaths for consistency.
We now use the built-in NoInfer util that comes with TS 5.4+.
Fixes
We fixed handling of the isSuccess status flag when switching infinite query cache entries. This should prevent accidental UI flashes that were occurring due to this flag accidentally flipping.
We've added a 100ms timeout fallback to the autoBatch enhancer's requestAnimationFrame timer. We had several reports that rAF didn't work correctly when used in background tabs / opened windows, and that RTK never updated the UI. This should ensure that the updates flush correctly.
What's Changed
Export hook options types for RTK Query hooks by @veeceey in #5218
Add TanStack Intent skills for Redux Toolkit by @phryneas in #5249
Keep isSuccess: true when switching infinite query cache entries by @riqts in #5268
fix: allow interface-based type guards as listener matcher by @riqts in #5269
fix: add setTimeout fallback to raf autoBatch strategy for background tabs by @riqts in #5273
chore(toolkit): rename IgnorePaths type to IgnoredPaths by @Ri5ha6h in #5284
feat(toolkit)!: switch to native NoInfer utility type by @aryaemami59 in #5289
This bugfix release updates the AbortSignal handling to fall back if DOMException isn't available (such as RN environments), and updates the TypedUseInfiniteQueryHookResult type to correctly include fetchNextPage/fetchPreviousPage fields.
Changelog
Bugfixes
The AbortSignal changes in 2.11.1 used DOMException in a couple places to match the expected behavior of AbortSignal, but turns out that's not available in environments like React Native. We've updated the logic to fall back to a plain Error if DOMException isn't available.
The TypedUseInfiniteQueryHookResult type wasn't correctly including the fetchNextPage/fetchPreviousPage fields, and now it does.
What's Changed
fix: use a normal Error when DOMException isn't available by @EskiMojo14 in #5161
Include page functions in TypedUseInfiniteQueryHookResult by @markerikson in #5165
This bugfix release fixes an issue with our internal AbortSignal handling that was reported as causing an error in a rare reset situation. We've also restructured our publishing process to use NPM Trusted Publishing, and updated our TS support matrix to only support TS 5.4+.
Changelog
Publishing Changes
We've previously done most of our releases semi-manually locally, with various release process CLI tools. With the changes to NPM publishing security and the recent wave of NPM attacks, we've updated our publishing process to solely use NPM Trusted Publishing via workflows. We've also done a hardening pass on our own CI setup.
We had done a couple releases via CI workflows previously, and later semi-manual releases caused PNPM to warn that RTK was no longer trusted. This release should be trusted and will resolve that issue.
We've previously mentioned rolling changes to our TS support matrix in release notes, but didn't officially document our support policy. We've added a description of the support policy (last 2 years of TS releases, matching DefinitelyTyped) and the current oldest TS version we support in the docs:
As of today, we've updated the support matrix to be TS 5.4+ . As always, it's possible RTK will work if you're using an earlier version of TS, but we don't test against earlier versions and don't support any issues with those versions.
We have run an initial test with the upcoming TS 7.0 native tsgo release. We found a couple minor issues with our own TS build and test setup, but no obvious issues with using RTK with TS 7.0.
Bug Fixes
A user reported a rare edge case where the combination of resetApiState and retry() could lead to an error calling an AbortController. We've restructured our AbortController handling logic to avoid that (and simplified a bit of our internals in the process).
This feature release upgrades our Immer dependency to v11 to pick up the additional recent performance optimizations, adds a new refetchCachedPages option to allow only fetching the first cached page, and fixes an issue with regex ignore paths in the immutability middleware.
Changelog
Immer v11 Performance Improvements
As described in the release notes for v2.10.0, we recently put significant effort into profiling Immer, and contributed several PRs that aimed to optimize its update performance.
v2.10.0 updated to use Immer 10.2.0, which added the first smaller set of perf updates. That included a new Immer option to disable "strict iteration" to speed up iterating copied objects, and we specifically applied that change in RTK under the assumption that standard plain JS objects as Redux state shouldn't have unusual keys anyway. Overall, this appears to boost Immer update perf by ~+20% over v10.1 depending on update scenario.
Immer v11.0.0 was just released and contains the second perf PR, a major internal architectural rewrite to change the update finalization implementation from a recursive tree traversal to a set of targeted updates based on accessed and updated fields. Based on the benchmarks in the PR, this adds another ~+5% perf boost over the improvements in v10.2, again with variations depending on update scenario. In practice, the actual improvement may be better than that - the benchmarks list includes some array update cases which actually got a bit slower (and thus drag down the overall average), and a majority of update scenarios show anywhere from +25% to +60% faster than Immer v10.1!
As a practical example, we have an RTK Query stress test benchmark where we mount 1000 components with query hooks at once, unmount, then remount them. We ran the same benchmark steps for RTK 2.9 and Immer 10.1, and then RTK 2.10+ and Immer 11. The overall scripting time dropped by about 30% (3330ms -> 2350ms), and the amount of time spent in Immer methods and the RTK reducers dropped significantly:
Based on this, it appears to be a major improvement overall.
As with the instructions in v2.10.0: if by some chance your Redux app state relies on non-string keys, you can still manually call setUseStrictIteration(true) in your app code to retain compatibility there, but we don't expect that standard Redux apps will have to worry about that.
There are still two outstanding Immer perf PRs that may offer further improvements: one that adds an optional plugin to override array methods to avoid proxy creation overhead, and another experimental tweak to shallow copying that may be better with larger object sizes.
New refetchCachedPages Option
RTK Query's infinite query API was directly based on React Query's approach, including the pages cache structure and refetching behavior. By default, that means that when you trigger a refetch, both R-Q and RTKQ will try to sequentially refetch all pages currently in that cache entry. So, if there were 5 pages cached for an entry, they will try to fetch pages 0...4, in turn.
Some users have asked for the ability to only refetch the first page. This can be accomplished somewhat manually by directly updating the cache entry to eliminate the old pages and then triggering a refetch, but that's admittedly not very ergonomic.
We've merged a contributed PR that adds a new refetchCachedPages flag. This can be defined as part of infinite query endpoints, passed as an option to infinite query hooks, or passed as an option in initiate() calls or hook refetch() methods. If set to refetchCachedPages: false, it will only refetch the first page in the cache and not the remaining pages, thus shrinking the cache from N pages to 1 page.
Other Fixes
We merged a fix to the immutability dev middleware where it was treating ignoredPath regexes as strings and not actually testing them correctly.
What's Changed
Update Immer to v11 for better update performance by @markerikson in #5141
fix: compare paths against Regex instances in ignoredPaths by @johnste in #5124
Add refetchCachedPages option for infinite query by @rossmartin in #5016
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Comment @coderabbitai help to get the list of available commands.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
2.10.1→2.13.0Release Notes
reduxjs/redux-toolkit (@reduxjs/toolkit)
v2.13.0Compare Source
This feature release updates our build tooling to TSDown and PNPM, adds official TypeScript 7 support, and includes a long list of bugfixes across RTK Query,
createAsyncThunk,createEntityAdapter, andcombineSlices.Changelog
Build Tooling Updates
We've fully modernizing modernized our build tooling across all of the Redux repos. That included switching from Yarn to PNPM, ESLint to Oxlint, Prettier to Oxfmt, and TSUp to TSDown.
The part that matters for users is that we now build the package with TSDown instead of
tsup. The package layout,exportsdefinitions, and exported APIs are all unchanged from 2.12. We've checked the new build withattw, and verified that CJS and ESM entry points load in both dev and prod builds, and that thelegacy-esmartifacts still target ES2017. The contents of the bundles do look a bit different (smaller CJS artifacts, slightly different helper output in thelegacy-esmfiles). If you see any behavior differences that look build-related, please file an issue!This is also our first release published via the updated PNPM-based workflow, still using NPM Trusted Publishing. We've also added
pkg.pr.newpreviews for every commit, so you can try out a PR build before it's released.Docs Updates
We've shipped a new combined Redux libraries docs site! The core docs site at https://redux.js.org now contains the docs for all of our libraries: Redux core and usage guides, Redux Toolkit, React Redux, and Reselect. The prior standalone docs sites for RTK, R-R, and Reselect now redirect to their respective sections of the combined docs. We've also done a major cleanup pass on the docs, deduplicating pages that had similarities (like the Next.js or RTK2 migration pages that lived in both the core and RTK docs), and updating outdated content (modernizing example code snippets, deleting dead links, and making RTK and hooks the default patterns shown). The RTK content now lives at https://redux.js.org/toolkit/ .
TypeScript 7 Support
TS 7.0 (the native Go port) is now out! We fixed the remaining type errors in RTK when checked by TS 7.0 and 7.1, and TS 7.0 is now part of our CI test matrix.
Per our TS support policy of matching DefinitelyTyped's support window, we've also updated our support matrix to TS 5.6+. As always, RTK may still work with earlier versions, but we no longer test against them.
RTK Query Fixes
useQueryState(and thususeQuery) was passing a new inline selector touseSelectoron every render, and also reading the store directly during render. The selector is now memoized, and the direct store read is gone. This also fixes a bug whereisSuccesscould flip fromfalsetotrueon an unrelated re-render while a query was refetching after an error.isSuccessnow correctly staysfalsein that case.datanow reflects cache updates made viaupdateQueryDatawhile a refetch is in flight, instead of showing the previous result.Polling now reads the current cache state when each poll fires, rather than the state at the time the poll was scheduled. This means
skipPollingIfUnfocusedrespects focus loss that happens after scheduling, and polls stop if their cache entry was removed.We fixed a race where a duplicate query request rejected by the thunk condition could cause queued tag invalidations to run too early and be lost, leaving stale data in the cache.
Tags with falsy ids like
0now invalidate and clean up correctly.Lazy query hooks now re-subscribe correctly when effects restart while the hook state is preserved, such as with Fast Refresh or
<Activity>.Infinite queries no longer trigger
onQueryStartedwhen fetching past the end of the list, and the infinite query hook result type now includes the page error flags.fetchBaseQueryonly treats a URL as absolute if it starts with a scheme.We also fixed an error when rehydrating state for an endpoint name that has no definition.
Other Fixes
createAsyncThunkno longer swallows aborts that happen before thependingaction is dispatched, and now correctly setsrejectedWithValuewhenrejectWithValueis called with a falsy payload.createEntityAdapter'ssetAllnow keeps the last item when given duplicate IDs, matchingsetMany. The sorted adapter'supdateManynow merges multiple updates for the same ID before applying them.combineSlicesnow keeps its internal state proxy cache per instance, so multiple combined reducers no longer interfere with each other.The immutability check middleware now handles circular references in state.
The dynamic middleware now caches its composed middleware chains when the list of middleware hasn't changed.
What's Changed
pkg.pr.newby @aryaemami59 in #5256entityAdapter):setAllwith duplicate IDs keeps last occurrence (consistent withsetMany) by @JSap0914 in #5321createAsyncThunkaborts that happen before pending by @chatman-media in #5314useRef<T | undefined>(undefined)usages in RTK Query hooks by @DucMinhNe in #5315onQueryStartedfrom triggering at end-of-list by @joseph0926 in #5182remark-typescript-toolsand update to TS7 by @markerikson in #5390rejectedWithValuefor falsyrejectWithValuepayloads by @dfedoryshchev in #5395immutableStateInvariantMiddlewareby @hamed-bavar in #5433useQueryStateandisSuccessduring refetch-after-error by @markerikson in #5456Full Changelog: reduxjs/redux-toolkit@v2.12.0...v2.13.0
v2.12.0Compare Source
This feature release adds RTK usage skills files (via TanStack Intent) exports the RTK Query hook options types for reusability, fixes issues with infinite query status flags and batching handling, and makes some small TS improvements.
Changelog
Skills Files
We've generated agent skill files that are now included in the RTK package itself in a
skillsfolder. They cover using and migrating to modern RTK, client and server state management, and handling side effects. You can point your agent at these skills yourself, or use TanStack Intent to pick them up.TypeScript Improvements
The types for our RTK Query hook options are now exported, which lets you stop using
Parametersto extract those types for use in your own code.The types for listener middleware matchers were tweaked to allow
interface-based type guards, not justtype-based definitions.The internal
IgnorePathstype was renamed toIgnoredPathsfor consistency.We now use the built-in
NoInferutil that comes with TS 5.4+.Fixes
We fixed handling of the
isSuccessstatus flag when switching infinite query cache entries. This should prevent accidental UI flashes that were occurring due to this flag accidentally flipping.We've added a 100ms timeout fallback to the
autoBatchenhancer'srequestAnimationFrametimer. We had several reports thatrAFdidn't work correctly when used in background tabs / opened windows, and that RTK never updated the UI. This should ensure that the updates flush correctly.What's Changed
IgnorePathstype toIgnoredPathsby @Ri5ha6h in #5284NoInferutility type by @aryaemami59 in #5289Full Changelog: reduxjs/redux-toolkit@v2.11.2...v2.12.0
v2.11.2Compare Source
This bugfix release updates the
AbortSignalhandling to fall back ifDOMExceptionisn't available (such as RN environments), and updates theTypedUseInfiniteQueryHookResulttype to correctly includefetchNextPage/fetchPreviousPagefields.Changelog
Bugfixes
The
AbortSignalchanges in 2.11.1 usedDOMExceptionin a couple places to match the expected behavior ofAbortSignal, but turns out that's not available in environments like React Native. We've updated the logic to fall back to a plainErrorifDOMExceptionisn't available.The
TypedUseInfiniteQueryHookResulttype wasn't correctly including thefetchNextPage/fetchPreviousPagefields, and now it does.What's Changed
TypedUseInfiniteQueryHookResultby @markerikson in #5165Full Changelog: reduxjs/redux-toolkit@v2.11.1...v2.11.2
v2.11.1Compare Source
This bugfix release fixes an issue with our internal
AbortSignalhandling that was reported as causing an error in a rare reset situation. We've also restructured our publishing process to use NPM Trusted Publishing, and updated our TS support matrix to only support TS 5.4+.Changelog
Publishing Changes
We've previously done most of our releases semi-manually locally, with various release process CLI tools. With the changes to NPM publishing security and the recent wave of NPM attacks, we've updated our publishing process to solely use NPM Trusted Publishing via workflows. We've also done a hardening pass on our own CI setup.
We had done a couple releases via CI workflows previously, and later semi-manual releases caused PNPM to warn that RTK was no longer trusted. This release should be trusted and will resolve that issue.
Thanks to the e18e folks and their excellent guide at https://e18e.dev/docs/publishing for making this process easier!
TS Support Matrix Updates
We've previously mentioned rolling changes to our TS support matrix in release notes, but didn't officially document our support policy. We've added a description of the support policy (last 2 years of TS releases, matching DefinitelyTyped) and the current oldest TS version we support in the docs:
As of today, we've updated the support matrix to be TS 5.4+ . As always, it's possible RTK will work if you're using an earlier version of TS, but we don't test against earlier versions and don't support any issues with those versions.
We have run an initial test with the upcoming TS 7.0 native
tsgorelease. We found a couple minor issues with our own TS build and test setup, but no obvious issues with using RTK with TS 7.0.Bug Fixes
A user reported a rare edge case where the combination of
resetApiStateandretry()could lead to an error calling anAbortController. We've restructured ourAbortControllerhandling logic to avoid that (and simplified a bit of our internals in the process).What's Changed
Full Changelog: reduxjs/redux-toolkit@v2.11.0...v2.11.1
v2.11.0Compare Source
This feature release upgrades our Immer dependency to v11 to pick up the additional recent performance optimizations, adds a new
refetchCachedPagesoption to allow only fetching the first cached page, and fixes an issue with regex ignore paths in the immutability middleware.Changelog
Immer v11 Performance Improvements
As described in the release notes for v2.10.0, we recently put significant effort into profiling Immer, and contributed several PRs that aimed to optimize its update performance.
v2.10.0 updated to use Immer 10.2.0, which added the first smaller set of perf updates. That included a new Immer option to disable "strict iteration" to speed up iterating copied objects, and we specifically applied that change in RTK under the assumption that standard plain JS objects as Redux state shouldn't have unusual keys anyway. Overall, this appears to boost Immer update perf by ~+20% over v10.1 depending on update scenario.
Immer v11.0.0 was just released and contains the second perf PR, a major internal architectural rewrite to change the update finalization implementation from a recursive tree traversal to a set of targeted updates based on accessed and updated fields. Based on the benchmarks in the PR, this adds another ~+5% perf boost over the improvements in v10.2, again with variations depending on update scenario. In practice, the actual improvement may be better than that - the benchmarks list includes some array update cases which actually got a bit slower (and thus drag down the overall average), and a majority of update scenarios show anywhere from +25% to +60% faster than Immer v10.1!
As a practical example, we have an RTK Query stress test benchmark where we mount 1000 components with query hooks at once, unmount, then remount them. We ran the same benchmark steps for RTK 2.9 and Immer 10.1, and then RTK 2.10+ and Immer 11. The overall scripting time dropped by about 30% (3330ms -> 2350ms), and the amount of time spent in Immer methods and the RTK reducers dropped significantly:
Based on this, it appears to be a major improvement overall.
As with the instructions in v2.10.0: if by some chance your Redux app state relies on non-string keys, you can still manually call
setUseStrictIteration(true)in your app code to retain compatibility there, but we don't expect that standard Redux apps will have to worry about that.There are still two outstanding Immer perf PRs that may offer further improvements: one that adds an optional plugin to override array methods to avoid proxy creation overhead, and another experimental tweak to shallow copying that may be better with larger object sizes.
New
refetchCachedPagesOptionRTK Query's infinite query API was directly based on React Query's approach, including the pages cache structure and refetching behavior. By default, that means that when you trigger a refetch, both R-Q and RTKQ will try to sequentially refetch all pages currently in that cache entry. So, if there were 5 pages cached for an entry, they will try to fetch pages 0...4, in turn.
Some users have asked for the ability to only refetch the first page. This can be accomplished somewhat manually by directly updating the cache entry to eliminate the old pages and then triggering a refetch, but that's admittedly not very ergonomic.
We've merged a contributed PR that adds a new
refetchCachedPagesflag. This can be defined as part of infinite query endpoints, passed as an option to infinite query hooks, or passed as an option ininitiate()calls or hookrefetch()methods. If set torefetchCachedPages: false, it will only refetch the first page in the cache and not the remaining pages, thus shrinking the cache from N pages to 1 page.Other Fixes
We merged a fix to the immutability dev middleware where it was treating
ignoredPathregexes as strings and not actually testing them correctly.What's Changed
Full Changelog: reduxjs/redux-toolkit@v2.10.1...v2.11.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.