Skip to content

Releases: reduxjs/react-redux

v8.0.0-beta.3

06 Feb 19:56
Compare
Choose a tag to compare
v8.0.0-beta.3 Pre-release
Pre-release

This beta release fixes a regression with unsubscribe performance in useSelector, and does some minor internal cleanup in connect.

At this point, React-Redux v8 is likely feature-complete and stable. We still really want users to try this out and give us feedback before the final release! We'd also like to add some additional tests around SSR behavior.

The tentative plan is to do a final review of the code and behavior after React 18 goes final, then release React-Redux v8 final shortly after that.

Changelog

useSelector Unsubscribe Performance

In 2019, we fixed a a reported issue with useSelector unsubscriptions showing quadratic performance, due to use of a single listeners array in our Subscription class. The fix was to switch to using a linked list to track subscribers.

When we reworked useSelector to use useSyncExternalStore for v8, we passed store.subscribe directly and stopped subscribing via a Subscription instance, thinking that we might no longer need Subscription any more. However, Subscription is still used by <Provider>, so it won't be removed from the bundle anyway, and the switch to using store.subscribe regressed the unsubscription performance because it does still use a listeners array as well.

We've switched back to having useSelector subscribe to the Subscription instance from <Provider>, and verified that this re-resolves the unsubscription performance behavior. We've also added a perf test to ensure that we capture this intended behavior and don't accidentally regress on this again in the future.

Internal Cleanup

We've removed a couple additional references to the removed pure option in connect, and tweaked some of the types to remove a legacy signature for Provider that is no longer relevant.

What's Changed

  • test: Adjust type tests to be compatible with React 18 typings by @eps1lon in #1868
  • Switch back to Subscription in useSelector to fix unsubscribe perf by @markerikson in #1870
  • Cleanup more code after pure removal by @Andarist in #1859

Full Changelog: v8.0.0-beta.2...v8.0.0-beta.3

v8.0.0-beta.2

22 Dec 22:05
Compare
Choose a tag to compare
v8.0.0-beta.2 Pre-release
Pre-release

This beta release makes several fixes to the TypeScript types for v8, fixes several dev dependencies that were accidentally listed as dependencies, and adds initial React 18 SSR support.

Changelog

TypeScript Fixes

The initial TS conversion effort ported a chunk of the typetests from the React-Redux v7 types in DefinitelyTyped. We've ported over the remainder of the typetests, which uncovered a few bugs and missing types (such as the useStore hook not being generic).

Those issues are now fixed, and after some additional tweaks all of the typetests are now passing. This means that existing TS usage of React-Redux v7 should be able to work entirely as-is with v8.

React 18 SSR Support

The new React 18 useSyncExternalStore hook accepts a function to supply the current state when called, which is normally the Redux store.getState method. However, a mutable store like Redux could change before or during an initial hydration render (such as a manual store.dispatch() before calling hydrateRoot(), or React components dispatching actions during the mount process). To avoid that, useSyncExternalStore also requires that you provide a getServerSnapshot function that can return a consistent single state value. uSES will use that all the way through the initial hydration render, and then check to see if any further updates are needed based on the latest state after the hydration render is complete.

The Provider component now accepts an optional serverState prop. If you're doing SSR, serialize your Redux store state on the server and pass that in to Provider as <Provider store={store} serverState={window.initialServerState}>, similar to how you would initialize a Redux store with that value.

We've updated both useSelector and connect to use the serverState value if it exists and pass that to useSyncExternalStore. This has been only briefly tested so far, but it appears to correctly eliminate hydration mismatch warnings.

We would really like more users to try this out and give us feedback!

Huge thanks to @Ephem for providing an SSR example to work with, and @acdlite for the API idea.

Dependency Updates

React-Redux now expects React 18 RC as a peer dep.

Several test libraries were accidentally added as dependencies in the previous betas, so they would get installed in user projects as well. Those have been moved back to devDependencies as intended.

What's Changed

  • fix: Add types to ensure that there will be no compilation errors when struct: false by @duan602728596 in #1851
  • Port remaining v7 typetests and improve v8 types by @markerikson in #1855
  • Add initial SSR support for React 18 and React-Redux v8 by @markerikson in #1835

Full Changelog: v8.0.0-beta.1...v8.0.0-beta.2

v8.0.0-beta.1

20 Nov 00:45
Compare
Choose a tag to compare
v8.0.0-beta.1 Pre-release
Pre-release

This beta bugfix release fixes incorrect initialization of the useSyncExternalStore hook from beta.0 that caused it to crash on startup. Sorry!

npm i react-redux@next

yarn add react-redux@next

What's Changed

  • Rework uSES init to not rely on module initialization order by @markerikson in #1845

v8.0.0-beta.0...v8.0.0-beta.1

v8.0.0-beta.0

19 Nov 04:40
Compare
Choose a tag to compare
v8.0.0-beta.0 Pre-release
Pre-release

This beta release adds a new 'react-redux/compat' entry point for use with React 16.9+ 17.x, re-enabling broader compatibility across React versions to make it easier to upgrade to React-Redux v8.

While there are no other changes since the previous alphas (and there's really been very minimal feedback reported on the alphas thus far), we believe the v8 pre-releases are stable enough to begin seriously evaluating them as upgrades in your apps. This also aligns with React 18 being upgraded to beta status and the useSyncExternalStore API stabilizing.

We would really appreciate users trying out this release with all compatible versions of React and reporting the results, even if it's just "yup, tried it and it works"! Please provide feedback in the linked discussion thread.

Overall, v8.0's major changes include:

  • Conversion of the codebase to TypeScript (no more @types/react-redux)
  • Use of React's new useSyncExternalStore API for React 18 compat
  • Removal of unused legacy APIs (connectAdvanced, the pure option for connect)
  • Modernization of build artifact compilation

For more details on those, see the v8.0.0-alpha.0 release notes.

Note: this release has a crash bug that is fixed in v8.0.0-beta.1 - please be sure to install the next tag or beta.1 specifically

npm i react-redux@next

yarn add react-redux@next

Changelog

New "Compat" Entry point

In 8.0.0-alpha.0, we switched the internals of connect and useSelector to use the new useSyncExternalStore API from React. At the time, that was only available in the form of a "shim" package that worked with multiple React versions.

In 8.0.0-alpha.1, useSyncExternalStore had been added to React itself. The original plan was always to make React-Redux v8 have a hard dependency on React 18, and the shim adds about 750 bytes to bundle size, so we dropped use of the shim entirely.

After suggestions from the community, we've now added a new 'react-redux/compat' entry point that falls back to using the shim. This should enable React-Redux v8 to work correctly with earlier versions of React that support hooks (16.9+ and 17.x), as well as Preact (which does not appear to be implementing useSyncExternalStore at this time).

We've updated our test suite to run all tests against both React 18 and the standard entry point with no uSES shim, and React 17 and the "compat" entry point with the uSES shim, and all tests are passing.

The likely approach for using this would be to alias or override your build setup to redirect imports of 'react-redux' to the 'react-redux/compat' entry point instead.

What's Changed

  • Add a "compat" entry point that works with React 16.9+ and 17 by @markerikson in #1842

v8.0.0-alpha.1...v8.0.0-beta.0

v8.0.0-alpha.1

02 Nov 03:25
Compare
Choose a tag to compare
v8.0.0-alpha.1 Pre-release
Pre-release

This alpha preview release updates our React dependencies to the latest React 18 alpha versions, updates the internal usages of useSyncExternalStore to match those alpha changes, and changes the peerDependencies to specifically require React 18 alpha or beta versions.

npm i react-redux@next

yarn add react-redux@next

Changelog

React 18 Alpha Updates

Since the previous React-Redux alpha, several more React 18 alpha versions have been released, some with meaningful changes. The useSyncExternalStore API has been promoted from the React "experimental" builds to the "alpha" channel, and the shim package's exports layout has been changed.

This release updates our internals to specifically import useSyncExternalStore from React itself. This means that starting with this release, React-Redux v8 requires a recent React 18 alpha/beta release that contains that API!

We'd appreciate folks trying this out with recent React builds and giving us feedback in the related issue:

Investigation: try out React-Redux v7 / v8 with React 18 alpha

What's Changed

Full Changelog: v8.0.0-alpha.0...v8.0.0-alpha.1

v7.2.6

25 Oct 17:12
0bcaec4
Compare
Choose a tag to compare

Just a quick fix for a Yarn install warning. Sorry about the noise!

Changes

  • Remove workspaces from our package.json to silence a Yarn warning (@timdorr)

v8.0.0-alpha.0

03 Oct 18:47
Compare
Choose a tag to compare
v8.0.0-alpha.0 Pre-release
Pre-release

This is the initial alpha preview release for React-Redux v8.

This alpha release reworks useSelector and connect for compatibility with React 18, rewrites the React-Redux codebase to TypeScript (obsoleting use of @types/react-redux), modernizes build output, and removes the deprecated connectAdvanced API and the pure option for connect.

npm i react-redux@next

yarn add react-redux@next

Overview and Compatibility

This alpha release is intended for initial compatibility testing with React 18 and TypeScript. For general discussion of this release, see the associated thread in the Discussions section.

Our public API is still the same ( connect and useSelector/useDispatch), all of our tests pass, and apps should run okay. It's very possible that the only migration needed is to bump the package version.

However, it's likely that there will be types breakage due to the TypeScript migration, and runtime bugs are also possible due to the amount of internal refactoring and changes.

React-Redux now requires the new experimental useSyncExternalStore API in React 18. This release is using the "shim" package which backfills that API in earlier React versions, and currently lists 'react': '^16 || ^17 || 18' as its acceptable peer dependencies, so in theory it could run with React 16 and 17. However, we're planning to remove use of the shim and have a hard dependency on React 18 by the time version 8.0 goes final, so you are enouraged to try out this build with an "experimental" build of React 18 that contains useSyncExternalStore, such as version 0.0.0-experimental-7d38e4fd8-20210930, and follow the React 18 upgrade instructions.

React 18 will be introducing new APIs related to SSR and hydration, and React-Redux will likely need further updates to support those. This release stubs out the getServerSnapshot argument to useSyncExternalStore - we'll tackle this in a future alpha release.

Changelog

TypeScript Migration

The React-Redux library source has always been written in plain JS, and the community maintained the TS typings separately as @types/react-redux.

We've (finally!) migrated the React-Redux codebase to TypeScript, using the existing typings as a starting point. We've tried to maintain the same external type signatures as much as possible, but there will most likely be some compile breakages from the changes, and we may have missed some bits along the way. Please file issues with any apparent TS-related problems so we can review them.

The TS migration was a great collaborative effort, with many community members contributing migrated files. Thank you to everyone who helped out!

As part of the process, we also updated the repo to use Yarn 2, copied the typetests files from DefinitelyTyped and expanded them, and improved our CI setup to test against multiple TS versions.

Note When testing this out, you should remove the @types/react-redux package and ensure that any installed copies of redux are de-duped. You are also encouraged to update to the latest versions of Redux Toolkit (1.6.1+) or Redux (4.1.1), to ensure consistency between installed types and avoid problems from types mismatches.

React 18 Compatibility

Per the React 18 announcement overview, React 18 will include new capabilities like automatic render batching and opt-in support for "concurrent rendering". In order for external state libraries like Redux to take advantage of those, we need to use the new useSyncExternalStore API to let React better coordinate renders caused by external updates.

We've reworked both connect and useSelector to call useSyncExternalStore internally. This process is purely internal refactoring, and should require no changes to your own code.

Early performance benchmarks show parity with React-Redux v7.2.5 for both connect and useSelector, so we do not anticipate any meaningful performance regressions.

Modernized Build Output

We've always targeted ES5 syntax in our published build artifacts as the lowest common denominator. Even the "ES module" artifacts with import/export keywords still were compiled to ES5 syntax otherwise.

With IE11 now effectively dead and many sites no longer supporting it, we've updated our build tooling to target a more modern syntax equivalent to ES2017, which shrinks the bundle size slightly.

If you still need to support ES5-only environments, please compile your own dependencies as needed for your target environment.

Removal of Legacy APIs

We announced in 2019 that the legacy connectAdvanced API would be removed in the next major version, as it was rarely used, added internal complexity, and was also basically irrelevant with the introduction of hooks. As promised, we've removed that API.

We've also removed the pure option for connect, which forced components to re-render regardless of whether props/state had actually changed if it was set to false. This option was needed in some cases in the early days of the React ecosystem, when components sometimes relied on external mutable data sources that could change outside of rendering. Today, no one writes components that way, the option was barely used, and React 18's useSyncExternalStore strictly requires immutable updates. So, we've removed the pure flag.

Given that both of these options were almost never used, this shouldn't meaningfully affect anyone.

Changes

Due to the TS migration effort and number of contributors, this list covers just the major changes:

v7.2.4...v8.0.0-alpha.0

v7.2.5

04 Sep 19:42
Compare
Choose a tag to compare

This release shrinks the size of our internal Subscription class, and updates useSelector to avoid an unnecessary selector call on mount.

Changes

Subscription Size Refactor

Our internal Subscription implementation has been written as a class ever since it was added in v5. By rewriting it as a closure factory, we were able to shave a few bytes off the final bundle size.

useSelector Mount Optimization

A user noticed that useSelector had never been given an early "bail out if the root state is the same" check to match how connect works. This resulted in a usually-unnecessary second call to the provided selector on mount. We've added that check.

Entry Point Consolidation

We've consolidated the list of exported public APIs into a single file, and both the index.js and alternate-renderers.js entry points now re-export everything from that file. No meaningful change here, just shuffling lines of code around for consistency.

Other Updates

React-Redux v8 and React 18 Development

With the announcement of React 18, we've been working with the React team to plan our migration path to keep React-Redux fully compatible with React's upcoming features.

We've already migrated the React-Redux main development branch to TypeScript, and are prototyping compatibility implementation updates. We'd appreciate any assistance from the community in testing out these changes so that we can ensure React-Redux works great for everyone when React 18 is ready!

Internal Tooling Updates

Our master branch now uses Yarn v2 for package management, is built with TypeScript, and we've made CI updates to test against multiple TS versions.

The 7.x branch has also been updated to use Yarn v2 for consistency.

These only affect contributors to the React-Redux package itself.

Changelog

v7.2.4...v7.2.5

v7.2.4

24 Apr 18:26
Compare
Choose a tag to compare

This release drops our dependency on the core redux package by inlining bindActionCreators, and tweaks useSelector to ensure that selectors aren't run an extra time while re-rendering.

Changelog

Redux Dependency Removal

React-Redux has always imported the bindActionCreators utility from the core redux package for use in connect. However, that meant that we had to have a peer dependency on redux, and this was the only reason we actually required that redux be installed. This became more annoying with the arrival of Redux Toolkit, which has its own dependency on redux internally, and thus users typically saw peer dependency warnings saying that "redux isn't listed as a dependency in your app".

Code reuse across separate packages is a great thing, but sometimes the right thing to do is duplicate code. So, we've inlined bindActionCreators directly into React-Redux, and we've completely dropped the dependency on Redux. This means that React-Redux will no longer produce a peerDep warning when used with Redux Toolkit, and <Provider> and connect really only need a Redux-store-compatible value to work right.

useSelector Fixes

Users reported that useSelector was re-running selector functions again unnecessarily while rendering after a dispatch. We've tweaked the logic to ensure that doesn't happen.

useSelector also now has checks in development to ensure that selector and equalityFn are functions.

Changes

v7.2.3...v7.2.4

v7.2.3

23 Mar 00:40
Compare
Choose a tag to compare

This release improves behavior in useSelector by returning the existing reference if the newly returned selector result passes the equality check, and adds a hard dependency on the @types/react-redux package to ensure TS users always have the typedefs installed.

Changes

useSelector Results Reuse

Issue #1654 reported that useSelector was returning new references from a selector even if the equality comparison function returned true. This is because the equality check was only ever being performed during the action dispatch process.

We now run the equality comparison against the value calculated by the selector while rendering, and return the existing reference for consistency if the old and new values are considered equal. This should improve some cases where further derived values where being recalculated unnecessarily.

TS Types Now Included

React-Redux has always been written in plain JS, and the typedefs maintained by the community in DefinitelyTyped. We plan on eventually rewriting the library in TypeScript in a future React-Redux v8 release, but until then the types can stay in DT.

However, having to always manually install @types/react-redux is annoying, and some users have gotten confused by that. This release adds a hard dependency on @types/react-redux, so that if you install react-redux, you automatically get the types as well. This should simplify the process for TS users.

Docs Updates

We've made several docs updates recently:

  • Renamed "Quick Start" to "Getting Started" and "Static Typing" to "Usage with TypeScript"
  • Dropped the docs API versioning setup, as the legacy API version docs pages were rarely viewed and the versioning setup confused docs contributors
  • Moved the old "Intro > Basic Tutorial" to "Tutorials > Connect" and marked it as semi-obsolete

We are currently working on a new React-Redux tutorial that will teach the React-Redux hooks as the primary approach, based on the "UI and React" page in the Redux docs "Fundamentals" tutorial.

Changelog

v7.2.2...v7.2.3