v5.11.2
- fix: decode Uint8Array XML input as UTF-8 by @emme1t in https://github.com/NaturalIntelligence/fast-xml-parser/pull/875
- fix: type EntityDecoderOptions.setXmlVersion's version as a number by @YevheniiKotyrlo in https://github.com/NaturalIntelligence/fast-xml-parser/pull/880
- @emme1t made their first contribution in https://github.com/NaturalIntelligence/fast-xml-parser/pull/875
- @YevheniiKotyrlo made their first contribution in https://github.com/NaturalIntelligence/fast-xml-parser/pull/880
Full Changelog: https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.11.1...v5.11.2
v9.4.0-alpha.2
This alpha release fixes two bugs in useSignalSelector: stale values rendered in the gap between a dispatch and the store notification, and tracking proxies leaking out of values a selector held onto from an earlier run. It also cuts the cost of spreading or enumerating objects inside selectors, and adds test coverage for using useSignalSelector with RTK Query's hooks. The stock Provider and useSelector are unchanged.
npm install react-redux@alpha
This is still an alpha. Please try it out and give us feedback! The alpha.0 notes cover what useSignalSelector is and how to opt in.
Once a useSignalSelector hook had its full dependency graph built, its getSnapshot returned a cached result that only updated when the store notified subscribers. Normally that happens synchronously inside dispatch(), but there are several cases where React renders the component before that notification arrives:
- RTK's
configureStoreincludes theautoBatchEnhancer, which delays notifications for batched actions (like RTK Query'spendingandfulfilledactions) until the next animation frame - a parent re-renders for its own reasons in that gap
- a
useSelectorcomponent and auseSignalSelectorcomponent in the same tree render in the same pass - an action dispatched from a layout effect, which React picks up in its post-commit snapshot check
In all of these, useSignalSelector could render the previous value, and a useSelector and a useSignalSelector reading the same field could disagree within one render.
getSnapshot now checks whether store.getState() has moved since the cached result was computed. If it has, it re-runs the selector against the current state. useSignalSelector also now passes React a new getSnapshot when the selector reference changes, matching useSelector, so React's post-commit consistency check runs in the same cases it does for useSelector.
The render-time fallback path above runs the selector against raw state, and we assumed its result could never contain tracking proxies. That assumption was wrong. A selector that holds onto a value from an earlier tracked run, via a closure or a ref, can return a proxy from that earlier run.
RTK Query does exactly this: its query hooks keep the last result so they can show the previous data while a new arg loads. With a stable selectFromResult, the component received a proxy of the previous data during that window instead of the raw state object. Results from that path are now unwrapped the same way as the main path.
Spreading an object in a selector ({ ...state.user }), or using Object.keys/values/entries, Object.assign, JSON.stringify, or for...in, previously recorded a dependency on the object's key list plus one dependency per field. Reading every field of an immutably-updated object is equivalent to depending on the object's identity, so a full enumeration of a nested object now collapses into a single identity dependency on that object.
Partial enumerations still track precisely: Object.keys(obj).length, or reading only some fields after enumerating, keeps field-level dependencies. The root state object and arrays are excluded, since their tracking already works differently.
This mostly shows up with RTK Query, whose selectors spread each cache entry. In our RTK Query benchmark, useSignalSelector time per dispatch dropped by about 20-30%.
We've added an interop test suite that runs RTK Query's hooks on top of useSignalSelector, via a custom createApi:
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
import { useDispatch, useSignalSelector, useStore } from 'react-redux'
export const createApi = buildCreateApi(
coreModule(),
reactHooksModule({
hooks: { useDispatch, useSelector: useSignalSelector, useStore },
}),
)
The tests cover query phases, selectFromResult, mutations and invalidation, skip, arg changes, and render counts, which match useSelector exactly. The types line up too: useSignalSelector satisfies the hooks.useSelector option type with no casts.
Writing those tests turned up two bugs on the RTK side, both fixed in RTK 2.13.0. useQueryState passed a new inline selector to useSelector on every render, which forced useSignalSelector to re-run the full tracked selector on every render. It also let isSuccess flip on unrelated re-renders during a refetch after an error. With 2.13.0, useSignalSelector selector runs per dispatch in our RTK Query benchmark showed a ~30% drop vs alpha.2. We recommend 2.13.0+ if you try this setup.
10 s per scenario, this release vs 9.3.0, Chrome, react-dom/profiling, RTK 2.12.
| Scenario | Script | Blocked | Notes |
|---|---|---|---|
| tree-view | -54% | -77% | |
| many-components-many-slices | -31% | -54% | |
| realistic-slice-count | -27% | -80% | |
| deeptree-nested-hooks | -24% | -61% | |
| entity-list | -22% | -45% | |
| rapid-dispatch | -21% | -65% | |
| multi-selector-component | -20% | -82% | |
| price-ticker | -19% | -58% | stock drops frames |
| selective-update | -15% | -64% | |
| forms | -12% | -80% | |
| entity-list-array | -9% | -62% | |
| many-components-same-slice | +3% | +96% | flat; work moved into dispatch |
| rtkq-separate-queries | +4% | +21% | |
| one-component-many-slices | +28% | +32% | 20,000 top-level keys |
| derived-selectors | +53% | +144% |
Render counts match 9.3.0 within noise, except where stock drops frames under load.
rtkq-separate-queries moved from +9% in alpha.1 to +4%. derived-selectors and one-component-many-slices remain the two scenarios where useSignalSelector is slower than useSelector. Their numbers vary a lot between runs, and before/after runs of this release's changes showed no measurable difference for either.
- Add prototype signals+path-tracking implementation by @markerikson in #2318
Full Changelog: https://github.com/reduxjs/react-redux/compare/v9.4.0-alpha.1...v9.4.0-alpha.2
v2.13.0
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.
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.
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/ .
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.
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.
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.
- Additional publishing hardening by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5297
- ci: fix Playwright e2e tests in publish-ci examples by @aryaemami59 in https://github.com/reduxjs/redux-toolkit/pull/5310
- ci: publish preview packages on every commit via
pkg.pr.newby @aryaemami59 in https://github.com/reduxjs/redux-toolkit/pull/5256 - feat(codegen): migrate to oazapfts v7 by @Suto-Michimasa in https://github.com/reduxjs/redux-toolkit/pull/5228
- fix(combineSlices): scope stateProxyMap per instance to prevent cross-instance proxy collisions by @JSap0914 in https://github.com/reduxjs/redux-toolkit/pull/5319
- fix(entityAdapter): pre-merge same-ID updates in sorted adapter's updateMany by @JSap0914 in https://github.com/reduxjs/redux-toolkit/pull/5323
- fix(
entityAdapter):setAllwith duplicate IDs keeps last occurrence (consistent withsetMany) by @JSap0914 in https://github.com/reduxjs/redux-toolkit/pull/5321 - fix(query): reflect cache updates in hook data by @jtiret in https://github.com/reduxjs/redux-toolkit/pull/5327
- fix: don't swallow
createAsyncThunkaborts that happen before pending by @chatman-media in https://github.com/reduxjs/redux-toolkit/pull/5314 - Simplify
useRef<T | undefined>(undefined)usages in RTK Query hooks by @DucMinhNe in https://github.com/reduxjs/redux-toolkit/pull/5315 - fix(query): prevent
onQueryStartedfrom triggering at end-of-list by @joseph0926 in https://github.com/reduxjs/redux-toolkit/pull/5182 - fix(types): fix tsgo (TS 7.0) type errors and re-enable the native-preview CI job by @veksa in https://github.com/reduxjs/redux-toolkit/pull/5344
- ci: bump GitHub Actions to their latest versions by @aryaemami59 in https://github.com/reduxjs/redux-toolkit/pull/5358
- chore(toolkit): remove redundant and unused type declarations by @aryaemami59 in https://github.com/reduxjs/redux-toolkit/pull/5356
- Modernize CI examples by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5363
- fix(rtk-query): only treat a url as absolute when it starts with a scheme by @MahinAnowar in https://github.com/reduxjs/redux-toolkit/pull/5428
- Modern Tooling, Part 1: Oxlint by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5384
- Modern Tooling, Part 2: Oxfmt by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5385
- Modern Tooling, Part 3: TSDown and TS6 by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5386
- Modern Tooling, Part 4: Vitest type assertions by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5387
- Modern Tooling, Part 5: PNPM by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5388
- Modern Tooling, Part 6: TS7 by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5389
- Modern Tooling, Part 7: vendor
remark-typescript-toolsand update to TS7 by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5390 - Modern Tooling, Part 8: Vitest 5 by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5436
- Remove redundant RTK Query example projects by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5443
- Type the reducer builder implementation explicitly for TS 7.1 by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5446
- fix(toolkit): flag
rejectedWithValuefor falsyrejectWithValuepayloads by @dfedoryshchev in https://github.com/reduxjs/redux-toolkit/pull/5395 - Cache unchanged dynamic middleware chains by @OskarEichler in https://github.com/reduxjs/redux-toolkit/pull/5415
- Preserve delayed invalidations after duplicate query rejection by @OskarEichler in https://github.com/reduxjs/redux-toolkit/pull/5406
- Read current query state when scheduled polls fire by @OskarEichler in https://github.com/reduxjs/redux-toolkit/pull/5412
- fix(toolkit): prevent undefined endpoint reference by @adamaveray in https://github.com/reduxjs/redux-toolkit/pull/5377
- fix(toolkit): tag with a falsy id invalidation and cleanup by @petr-kratochvil in https://github.com/reduxjs/redux-toolkit/pull/5398
- fix(rtk-query): add infinite query page error flags to hook result type by @mvpowers in https://github.com/reduxjs/redux-toolkit/pull/5441
- Reinstate lazy queries after preserved effects restart by @OskarEichler in https://github.com/reduxjs/redux-toolkit/pull/5424
- fix(toolkit): handle circular references in
immutableStateInvariantMiddlewareby @hamed-bavar in https://github.com/reduxjs/redux-toolkit/pull/5433 - Fix TS7 errors and update TS matrix by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5455
- Fix unstable selector reference inside of
useQueryStateandisSuccessduring refetch-after-error by @markerikson in https://github.com/reduxjs/redux-toolkit/pull/5456
Full Changelog: https://github.com/reduxjs/redux-toolkit/compare/v2.12.0...v2.13.0
v16.4.0-canary.52
- [test] Stabilize middleware revalidation test: #99378
- test: scope loader build dependency update to Turbopack: #99380
- Remove CLAUDE.md symlinks in favor of AGENTS.md: #98910
- Align ExecuteContext task accessor names: #99258
- [test] Stabilize responsive dev overlay header layout test: #99376
- Turbopack: skip trimmed side-effect imports in SideEffectsModule: #95781
- Turbopack: preserve import
withclauses when direct-binding: #95529 - Turbopack: fix split_module correctness for app-router: #95522
- Turbopack: fix empty tree-shake chunks desyncing part ids (#93424): #95516
- Fix custom cache handlers missing on initial requests: #99372
- Allow Draft Mode on unlisted closed routes in adapter deployments: #99370
- Fix bundle analyzer source table delta sorting: #99369
- test: fix stale snapshots after
unstable_{prefetch,navigation}rename: #99371 - Virtualize bundle analyzer source table: #98539
- [PPF] Remove leftover debug log in router: #99365
- Remove unstable_ prefix from navigation() and prefetch(): #99241
- Lazy dynamic imports for ssr: #98836
- Refine the Security Insight upgrade prompt: #99354
- [PPF]
ensureStatic = "navigation": #99171 - docs: use prefetch={true} for links to ISR pages with Cache Components: #99261
- Add agent feedback to create-next-app defaults: #99119
- Make next-dev-loop browser headless by default: #98318
- [test] Extend timeout for tests barely below it: #99305
- docs: typo fixes: #99350
- [ai-upgrade] ESC to move back during prompt: #99319
- [ai-upgrade] Ask user to choose permission: #99291
- [ai-upgrade] Ask user to choose model and effort: #99235
- [ai-upgrade] Ask user whether to start upgrade in worktree: #99232
Huge thanks to @unstubbable, @jimmyhmiller, @jarrensj, @lukesandberg, @wbinnssmith, @lubieowoce, @icyJoseph, @aurorascharff, @eps1lon, and @devjiwonchoi for helping!
test v0.6.2
-
Declare which package modules have side effects.
-
Bumped
@remix-run/*dependencies: