react-redux
9.3.1 · 27 Oct 2026MIT54.9M / weekRepositorynpmAtom feed
105 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
- 9.x · latest line
9.3.1
27 Oct 2026- breaking
Switch to native
NoInferutility type connect: LogmapStateToPropserrors toconsole.errorin devconnect: SplitmapStateToProps/mapDispatchToPropsunions into ordered overloads
This bugfix release fixes
connecttype inference under TS 7, fixes severalconnectandProviderruntime bugs, adds dev-mode logging for errors thrown inmapStateToProps, and updates our build tooling and TypeScript support matrix.Warning
While
connectis still published and technically supported, we officially deprecatedconnectin 9.3.0 and strongly recommend migrating to use the hooks APIs instead.Changelog
connectTypes and TS 7We had reports that
connectsometimes inferred the wrong props whenmapStateToPropsormapDispatchToPropswas a factory function. The connected component's props would collapse to{}, and a required prop would show up as "missing" at the call site.Turns out the
connectoverloads typed those arguments as unions of the factory form (() => (state) => props) and the plain form. TS7 changed the ordering of which union member got selected, so this broke.As Anders suggested in microsoft/typescript-go#977, we've split those unions into separate overloads listed in order of preference, factory form first. Overload matching no longer depends on how the compiler orders a union. We then applied the same fix to the
mergePropsoverloads, which still failed under TS 7.Bug Fixes
Providernow usesserverStatewhen it's a falsy value like0,false, or''. Previously it checked for truthiness, so a falsy root state fell back to the client store's state during SSR and hydration.nullandundefinedare still treated as "no server state".A connected component's
contextprop is now honored in production. The assignment that picked up the custom context sat inside the development-only validation block. In production, a component with only a custom provider would throw, and one rendered under both providers would read the default provider's store.connectno longer overrides arefpassed as a regular prop whenforwardRefisn't enabled (#2251). With React 19's ref-as-prop, the wrapper was always passing its ownref(undefinedwithoutforwardRef), which replaced the one you passed in.An explicit
dependsOnOwnProps = falseon amapStateToPropsormapDispatchToPropsfunction is now respected. We had been ignoring it for functions declared with two parameters, even though the option exists specifically for functions whoselengthisn't reliable.Rendering
<Provider>in a React Server Component without"use client"now throws a clear dev-mode error that tells you what's wrong, instead of failing with "useIsomorphicLayoutEffect is not a function" (#2082). Setups that resolve thereact-serverexport condition already got a clear error. This covers the setups that don't.mapStateToPropsError LoggingSince v8, an error thrown in
mapStateToPropsduring a store update has been caught in the subscription callback and then effectively swallowed. The component just kept rendering its previous props (#1942).connectnow logs those errors toconsole.errorin development, so they show up in DevTools. Production behavior is unchanged.TypeScript Support
The internal
NoInferhelper type has been replaced with TypeScript's built-inNoInfer, which was added in TS 5.4. That makes TS 5.4 the minimum version for React-Redux's types. Our CI matrix now covers TS 5.6 through 5.9, 6.0, 7.0, andnext.Build Tooling
We've moved the repo to pnpm, Oxlint, and Oxfmt, and switched the library build from tsup to tsdown. The package
exportslayout is unchanged, but the build output comes from a different bundler. If you see any packaging or import problems with this release, please file an issue.What's Changed
connect: LogmapStateToPropserrors toconsole.errorin dev- breaking
Switch to native
NoInferutility type connect: SplitmapStateToProps/mapDispatchToPropsunions into ordered overloadsModern Tooling, Part 1: PNPM
Fix TS7 errors and update TS matrix
Provider: Throw a clearer error when rendered in a React Server ComponentRespect falsy server snapshots and production context overrides
Don't override ref property when not configured to.
Honour explicit
dependsOnOwnProps=falsein getDependsOnOwnProps
9.3.0
15 May 2026- deprecated
Mark
connectas deprecated
This feature release officially marks the
connectAPI as deprecated.That's it. That's the release. :)
Changelog
connectdeprecationWay back in 2022, I officially marked the original Redux core
createStoremethod as deprecated in Redux 4.2.0. As I clearly stated in that release, the goal of markingcreateStoreas deprecated was to encourage users to migrate to modern Redux Toolkit, especially for those users who don't read our docs (such as beginners following outdated tutorials or in bootcamps, etc). The change was visual-only - adding@deprecatedjust marks the import with a strikethrough in an IDE, and the docblock references the "use modern Redux Toolkit" docs page. No runtime errors, no behavior changes, just an indication that the function is considered obsolete and you shouldn't use it directly any more. I also exported alegacy_createStorealias - same function, no deprecation attribute.It's 4 years later, and I'm finally doing the same thing for
connect:)Again, nothing about
connect's behavior is changing, and we do not intend to remove theconnectAPI. But it's 2026, and hooks are the correct way to use React and React-Redux today.We do strongly encourage users to migrate from
connectto theuseSelector / useDispatchhooks in general. This should result in codebases that are easier to understand and ought to improve performance slightly due to the way updates are handled.As with before, React-Redux now exports a
legacy_connectalias that does not have the deprecation attribute applied.Trusted Publishing Fixed
We had set up trusted publishing for React-Redux a couple years ago and did some releases with that enabled, but at some point I did a follow-up release that still used the previous manual workflow, and that lost the trusted publishing provenance flag. We had recent issues requesting a new release with trusted publishing enabled again, so we've fixed that with this release.
What's Changed
- deprecated
Mark
connectas deprecated
9.2.0
10 Dec 2024Improve treeshakeability of build artifacts
Migrate to React
Migrate to React 19 (take 2)
This feature release updates the React peer dependency to work with React 19, and improves treeshakeability of our build artifacts.
Changelog
React 19 Compat
React 19 was just released! We've updated our peer dep to accept React 19, and updated our runtime and type tests to check against both React 18 and 19.
Also see Redux Toolkit v2.5.0 for the same peer dep update.
Treeshaking
We've done some nitty-gritty optimization work to ensure bundlers correctly treeshake unused parts of the bundle.
What's Changed
Improve treeshakeability of build artifacts
Migrate to React
Migrate to React 19 (take 2)
Clean up devdeps
9.1.2
2 May 2024React-Redux has a peer dep on RN
RN has a peer dep on React 18.2
But the latest React, 18.3 would get installed in the app
This bugfix release removes the no-longer-necessary peer dependency on
react-native, and tweaks a few TS types for compat with the upcoming React 19 release.Changes
React Native Peer Dependency Removed
We've always had an awkward peer dependency on both ReactDOM and React Native, because of the need to import the
unstable_batchedUpdatesAPI directly from each reconciler. That's part of what led to the sequence of 9.x patch releases to deal with RN compat.As of 9.0.3, we dropped the batching imports completely, since React 18 now batches by default. That means we didn't even have any remaining imports from
react-native.Meanwhile, React 18.3 just came out, but so did React Native 0.74. RN 0.74 still requires React 18.2.
This caused NPM users to have installation failures when trying to use React-Redux:
React-Redux has a peer dep on RN
RN has a peer dep on React 18.2
But the latest React, 18.3 would get installed in the app
NPM errors with a peer dep mismatch
We no longer need to list RN as a peer dep, and dropping that also fixes the NPM installation issues as well.
What's Changed
Fix
useRefusages to be called with an explicit argument ofundefined.Replace usage of deprecated
JSXglobal namespace withReact.JSXDrop now-unneeded RN peer dep
Fix remaining React 19 types issues
9.1.1
14 Apr 2024Remove unused isProcessingDispatch
Move
Equalsconstraint into an intersection type.Fix
useIsomorphicLayoutEffectusage in React Native environments
This bugfix release fixes an issue with
connectand React Native caused by changes to our bundling setup in v9. Nestedconnectcalls should work correctly now.What's Changed
Remove unused isProcessingDispatch
Move
Equalsconstraint into an intersection type.Fix
useIsomorphicLayoutEffectusage in React Native environments
9.1.0
12 Jan 2024Update hooks.md — reselect usage with multiple instances simplified
Modernize ESLint configuration
Introduce pre-typed hooks via
hook.withTypes<RootState>()method
This minor release adds a new syntax for pre-typing hooks.
.withTypesPreviously, the approach for "pre-typing" hooks with your app settings was a little varied. The result would look something like the below:
import type { TypedUseSelectorHook } from "react-redux" import { useDispatch, useSelector, useStore } from "react-redux" import type { AppDispatch, AppStore, RootState } from "./store" export const useAppDispatch: () => AppDispatch = useDispatch export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector export const useAppStore = useStore as () => AppStoreReact Redux v9.1.0 adds a new
.withTypesmethod to each of these hooks, analogous to the.withTypesmethod found on Redux Toolkit'screateAsyncThunk.The setup now becomes:
import { useDispatch, useSelector, useStore } from "react-redux" import type { AppDispatch, AppStore, RootState } from "./store" export const useAppDispatch = useDispatch.withTypes<AppDispatch>() export const useAppSelector = useSelector.withTypes<RootState>() export const useAppStore = useStore.withTypes<AppStore>()What's Changed
Update hooks.md — reselect usage with multiple instances simplified
Modernize ESLint configuration
Introduce pre-typed hooks via
hook.withTypes<RootState>()method
9.0.4
11 Dec 2023Allow react-native newer than 0.69 as peer dependency
This bugfix release updates the React Native peer dependency to be
>= 0.69, to better reflect the need for React 18 compat and (hopefully) resolve issues with thenpmpackage manager throwing peer dep errors on install.What's Changed
Allow react-native newer than 0.69 as peer dependency
9.0.3
10 Dec 2023- deprecated
Drop renderer-specific batching behavior and deprecate
batch Drop
@types/react-domand lower@types/reactto min needed
This bugfix release drops the ReactDOM / React Native specific use of render batching, as React 18 now automatically batches, and updates the React types dependencies
Changelog
Batching Dependency Updates
React-Redux has long depended on React's
unstable_batchedUpdatesAPI to help batch renders queued by Redux updates. It also re-exported that method as a util namedbatch.However, React 18 now auto-batches all queued renders in the same event loop tick, so
unstable_batchedUpdatesis effectively a no-op.Using
unstable_batchedUpdateshas always been a pain point, because it's exported by the renderer package (ReactDOM or React Native), rather than the corereactpackage. Our prior implementation relied on having separatebatch.tsandbatch.native.tsfiles in the codebase, and expecting React Native's bundler to find the right transpiled file at app build time. Now that we're pre-bundling artifacts in React-Redux v9, that approach has become a problem.Given that React 18 already batches by default, there's no further need to continue using
unstable_batchedUpdatesinternally, so we've removed our use of that and simplified the internals.We still export a
batchmethod, but it's effectively a no-op that just immediately runs the given callback, and we've marked it as@deprecated.We've also updated the build artifacts and packaging, as there's no longer a need for an
alternate-renderersentry point that omits batching, or a separate artifact that imports from"react-native".What's Changed
- deprecated
Drop renderer-specific batching behavior and deprecate
batch Drop
@types/react-domand lower@types/reactto min needed
9.0.2
5 Dec 2023Change react-native output extension from
.mjsto.js
This bugfix release makes additional tweaks to the React Native artifact filename to help resolve import and bundling issues with RN projects.
What's Changed
Change react-native output extension from
.mjsto.js
9.0.1
4 Dec 2023Add an RN-specific bundle and consolidate imports
This bugfix release updates the package to include a new
react-redux.react-native.jsbundle that specifically imports React Native, and consolidates all of the'react'imports into one file to save on bundle size (and enable some tricky React Native import handling).What's Changed
Add an RN-specific bundle and consolidate imports
9.0.0
4 Dec 2023Switches to requiring React 18 and Redux Toolkit 2.0 / Redux 5.0
Updates the packaging for better ESM/CJS compatibility and modernizes the build output
Updates the options for dev mode checks in
useSelector
This major release:
Switches to requiring React 18 and Redux Toolkit 2.0 / Redux 5.0
Updates the packaging for better ESM/CJS compatibility and modernizes the build output
Updates the options for dev mode checks in
useSelectorAdds a new React Server Components artifact that throws on use, to better indicate compat issues
This release has breaking changes.
This release is part of a wave of major versions of all the Redux packages: Redux Toolkit 2.0, Redux core 5.0, React-Redux 9.0, Reselect 5.0, and Redux Thunk 3.0.
For full details on all of the breaking changes and other significant changes to all of those packages, see the "Migrating to RTK 2.0 and Redux 5.0" migration guide in the Redux docs.
Note
The Redux core, Reselect, and Redux Thunk packages are included as part of Redux Toolkit, and RTK users do not need to manually upgrade them - you'll get them as part of the upgrade to RTK 2.0. (If you're not using Redux Toolkit yet, please start migrating your existing legacy Redux code to use Redux Toolkit today!)
React-Redux is a separate, package, but we expect you'll be upgrading them together.# React-Redux npm install react-redux yarn add react-redux # RTK npm install @reduxjs/toolkit yarn add @reduxjs/toolkit # Standalone Redux core npm install redux yarn add redux
Changelog
React 18 and RTK 2 / Redux core 5 Are Required
React-Redux 7.x and 8.x worked with all versions of React that had hooks (16.8+, 17.x, 18.x). However, React-Redux v8 used React 18's new
useSyncExternalStorehook. In order to maintain backwards compatibility with older React versions, we used theuse-sync-external-store"shim" package that provided an official userland implementation of theuseSyncExternalStorehook when used with React 16 or 17. This meant that if you were using React 18, there were a few hundred extra bytes of shim code being imported even though it wasn't needed.For React-Redux v9, we're switching so that React 18 is now required! This both simplifies the maintenance burden on our side (fewer versions of React to test against), and also lets us drop the extra bytes because we can import
useSyncExternalStoredirectly.React 18 has been out for a year and a half, and other libraries like React Query are also switching to require React 18 in their next major version. This seems like a reasonable time to make that switch.
Similarly, React-Redux now depends on Redux core v5 for updated TS types (but not runtime behavior). We strongly encourage all Redux users to be using Redux Toolkit, which already includes the Redux core. Redux Toolkit 2.0 comes with Redux core 5.0 built in.
ESM/CJS Package Compatibility
The biggest theme of the Redux v5 and RTK 2.0 releases is trying to get "true" ESM package publishing compatibility in place, while still supporting CJS in the published package.
The primary build artifact is now an ESM file,
dist/react-redux.mjs. Most build tools should pick this up. There's also a CJS artifact, and a second copy of the ESM file namedreact-redux.legacy-esm.jsto support Webpack 4 (which does not recognize theexportsfield inpackage.json). There's also two special-case artifacts: an "alternate renderers" artifact that should be used for any renderer other than ReactDOM or React Native (such as theinkReact CLI renderer), and a React Server Components artifact that throws when any import is used (since using hooks or context would error anyway in an RSC environment). Additionally, all of the build artifacts now live under./dist/in the published package.Previous releases actually shipped separate individual transpiled source files - the build artifacts are now pre-bundled, same as the rest of the Redux libraries.
Modernized Build Output
We now publish modern JS syntax targeting ES2020, including optional chaining, object spread, and other modern syntax. If you need to . If you need to target older browsers, please transpile the packages yourself (or use the
legacy-esmbuild artifact for ES2017).Build Tooling
We're now building the package using github.com/egoist/tsup. We also now include sourcemaps for the ESM and CJS artifacts.
Dropping UMD Builds
Redux has always shipped with UMD build artifacts. These are primarily meant for direct import as script tags, such as in a CodePen or a no-bundler build environment.
We've dropped those build artifacts from the published package, on the grounds that the use cases seem pretty rare today.
There's now a
react-redux.browser.mjsfile in the package that can be loaded from a CDN like Unpkg.If you have strong use cases for us continuing to include UMD build artifacts, please let us know!
React Server Components Behavior
Per Mark's post "My Experience Modernizing Packages to ESM", one of the recent pain points has been the rollout of React Server Components and the limits the Next.js + React teams have added to RSCs. We see many users try to import and use React-Redux APIs in React Server Component files, then get confused why things aren't working right.
To address that, we've added a new entry point with a
"react-server"condition. Every export in that file will throw an error as soon as it's called, to help catch this mistake earlier.Dev Mode Checks Updated
In v8.1.0, we updated
useSelectorto accept an options object containing options to check for selectors that always calculate new values, or that always return the root state.We've renamed the
noopCheckoption toidentityFunctionCheckfor clarity. We've also changed the structure of the options object to be:export type DevModeCheckFrequency = 'never' | 'once' | 'always' export interface UseSelectorOptions<Selected = unknown> { equalityFn?: EqualityFn<Selected> devModeChecks?: { stabilityCheck?: DevModeCheckFrequency identityFunctionCheck?: DevModeCheckFrequency } }hoist-non-react-staticsandreact-isDeps InlinedHigher Order Components have been discouraged in the React ecosystem over the last few years. However, we still include the
connectAPI. It's now in maintenance mode and not in active development.As described in the React legacy docs on HOCs, one quirk of HOCs is needing to copy over static methods to the wrapper component. The
hoist-non-react-staticspackage has been the standard tool to do that.We've inlined a copy of
hoist-non-react-staticsand removed the package dep, and confirmed that this improves tree-shaking.We've also done the same with the
react-ispackage as well, which was also only used byconnect.This should have no user-facing effects.
TypeScript Support
We've dropped support for TS 4.6 and earlier, and our support matrix is now TS 4.7+.
What's Changed
Update packaging, build config, and entry points for v9
Add stack to dev mode checks
Add an extra entrypoint for React Server Components
Inline hoist-non-react-statics to eliminate a dep and help shaking
Make context typing more accurate
Fix
uSESimports and run against RTK CI examplesCopy CI setup for RTK examples
Fix useSelector() in combination with lazy loaded components breaks with react v18
Actually add
sideEffects: "false"topackage.jsonin v9Inline
react-isutils to fix tree-shaking in 9.0Rename
noopChecktoidentityFunctionCheckUse scoped JSX for React types
- 8.x
8.1.3
1 Oct 2023Add stack to dev mode checks
Fix useSelector() in combination with lazy loaded components breaks with react v18
This bugfix release fixes an issue with subscriptions being lost when lazy-loaded components are used with React Suspense, and includes stack traces in
useSelectorusage warnings .What's Changed
Add stack to dev mode checks
Fix useSelector() in combination with lazy loaded components breaks with react v18
8.1.2
29 Jul 2023The behaviour of the "React Context Singletons" from 8.1.1 has been adjusted to also work if you have multiple React instances of the same version (those will now be separated) and if you are in an environment without
globalThis(in this case it will fall back to the previous behaviour).We do no longer use Proxies, which should help with some very outdated consumers, e.g. smart TVs, that cannot even polyfill Proxies.
This version changes imports from the React package to namespace imports so the package can safely be imported in React Server Components as long as you don't actually use it - this is for example important if you want to use the React-specifc
createApifunction from Redux Toolkit.Some other changes:
The behaviour of the "React Context Singletons" from 8.1.1 has been adjusted to also work if you have multiple React instances of the same version (those will now be separated) and if you are in an environment without
globalThis(in this case it will fall back to the previous behaviour).We do no longer use Proxies, which should help with some very outdated consumers, e.g. smart TVs, that cannot even polyfill Proxies.
8.1.1
21 Jun 2023Fix typescript error on non exported type
Create singleton context by React version
Remove RTK peerDep
This bugfix release tweaks the recent lazy context setup logic to ensure a single React context instance per React version, and removes the recently added RTK peerdep to fix an issue with Yarn workspaces.
Changelog
React Context Singletons
React Context has always relied on reference identity. If you have two different copies of React or a library in a page, that can cause multiple versions of a context instance to be created, leading to problems like the infamous "Could not find react-redux context" error.
In v8.1.0, we reworked the internals to lazily create our single
ReactReduxContextinstance to avoid issues in a React Server Components environment.This release further tweaks that to stash a single context instance per React version found in the page, thus hopefully avoiding the "multiple copies of the same context" error in the future.
What's Changed
Fix typescript error on non exported type
Create singleton context by React version
Remove RTK peerDep
8.1.0
13 Jun 2023Selectors will be called twice with the same inputs, and
useSelectorwill warn if the results are different referencesuseSelectorwill warn if the selector result is actually the entire rootstateCheck for Provider even when using custom context
This feature release adds new development-mode safety checks for common errors (like poorly-written selectors), adds a workaround to fix crash errors when React-Redux hooks are imported into React Server Component files, and updates our hooks API docs page with improved explanations and updated links.
Changelog
Development Mode Checks for
useSelectorWe've had a number of users tell us over time that it's common to accidentally write selectors that have bad behavior and cause performance issues. The most common causes of this are either selectors that unconditionally return a new reference (such as
state => state.todos.map()without any memoization ), or selectors that actually return the entire root state (state => state).We've updated
useSelectorto add safety checks in development mode that warn if these incorrect behaviors are detected:Selectors will be called twice with the same inputs, and
useSelectorwill warn if the results are different referencesuseSelectorwill warn if the selector result is actually the entire rootstate
By default, these checks only run once the first time
useSelectoris called. This should provide a good balance between detecting possible issues, and keeping development mode execution performant without adding many unnecessary extra selector calls.If you want, you can configure this behavior globally by passing the enum flags directly to
<Provider>, or on a per-useSelectorbasis by passing an options object as the second argument:// Example: globally configure the root state "noop" check to run every time <Provider store={store} noopCheck="always"> {children} </Provider>// Example: configure `useSelector` to specifically run the reference checks differently: function Component() { // Disable check entirely for this selector const count = useSelector(selectCount, { stabilityCheck: 'never' }) // run once (default) const user = useSelector(selectUser, { stabilityCheck: 'once' }) // ... }This goes along with the similar safety checks we've added to Reselect v5 alpha as well.
Context Changes
We're still trying to work out how to properly use Redux and React Server Components together. One possibility is using RTK Query's
createApito define data fetching endpoints, and using the generated thunks to fetch data in RSCs, but it's still an open question.However, users have reported that merely importing any React-Redux API in an RSC file causes a crash, because
React.createContextis not defined in RSC files. RTKQ's React-specificcreateApientry point imports React-Redux, so it's been unusable in RSCs.This release adds a workaround to fix that issue, by using a proxy wrapper around our singleton
ReactReduxContextinstance and lazily creating that instance on demand. In testing, this appears to both continue to work in all unit tests, and fixes the import error in an RSC environment. We'd appreciate further feedback in case this change does cause any issues for anyone!We've also tweaked the internals of the hooks to do checks for correct
<Provider>usage when using a custom context, same as the default context checks.Docs Updates
We've cleaned up some of the Hooks API reference page, and updated links to the React docs.
What's Changed
Check for Provider even when using custom context
Add a stability check, to see if selector returns stable result when called with same parameters.
Add an E2E-ish test that verifies behavior when imported into RSCs
Lazily create Context for RSC compat
Add warning for selectors that return the entire state
8.0.7
31 May 2023: Fix broken RTK peer dep
This release updates the peer dependencies to accept Redux Toolkit, and accept the ongoing RTK and Redux core betas as valid peer deps.
Note: These changes were initially in 8.0.6, but that had a typo in the peer deps that broke installation. Sorry!
What's Changed
Bump Redux peer deps to accept 5.0 betas, and bump RTK dev dep
: Fix broken RTK peer dep
8.0.6
30 May 2023This release updates the peer dependencies to accept Redux Toolkit, and accept the ongoing RTK and Redux core betas as valid peer deps.This release updates the peer dependencies to accept Redux Toolkit, and accept the ongoing RTK and Redux core betas as valid peer deps.This release has a peer deps typo that breaks installation - please use 8.0.7 instead !
What's Changed
Bump Redux peer deps to accept 5.0 betas, and bump RTK dev dep
8.0.5
4 Nov 2022Provider: pass state (S) generic through toProviderPropsWrap
equalityFntype inNoInferFix wrapped component prop types when passing nullish mapDispatchToProps
This release fixes a few minor TS issues.
What's Changed
Provider: pass state (S) generic through toProviderPropsWrap
equalityFntype inNoInferFix wrapped component prop types when passing nullish mapDispatchToProps
8.0.4
23 Sep 2022Don't require allowSyntheticDefaultImports: true
Fixed type issue with
ComponentPropsfrom older@types/reactconnect: Pass ownProps to areStatesEqual
This patch release fixes some minor TS types issues, and updates the rarely-used
areStatesEqualoption forconnectto now pass throughownPropsfor additional use in determining which pieces of state to compare if desired.Note: 8.0.3 was accidentally published without one of these fixes. Use 8.0.4 instead.
Changelog
TS Fixes
We've fixed an import of
Reactthat caused issues with theallowSyntheticDefaultImportsTS compiler flag in user projects.connectalready accepted a custom context instance asprops.context, and had runtime checks in case users were passing through a real value with app data asprops.contextinstead. However, the TS types did not handle that case, and this would fail to compile. If your own component expectsprops.contextwith actual data,connect's types now use that type instead.The
ConnectedProps<T>type had a mismatch with React's built-inReact.ComponentProps<Component>type, and that should now work correctly.Other Changes
The
areStatesEqualoption toconnectnow receivesownPropsas well, in case you need to make a more specific comparison with certain sections of state.The new signature is:
{ areStatesEqual?: ( nextState: State, prevState: State, nextOwnProps: TOwnProps, prevOwnProps: TOwnProps ) => boolean }What's Changed
Don't require allowSyntheticDefaultImports: true
Fixed type issue with
ComponentPropsfrom older@types/reactconnect: Pass ownProps to areStatesEqual
Omit built-in context prop if user component props include context
8.0.2
22 May 2022Show warning instead of throwing error that pure option has been removed
This patch release tweaks the behavior of
connectto print a one-time warning when the obsoletepureoption is passed in, rather than throwing an error. This fixes crashes caused by libraries such asreact-beautiful-dndcontinuing to pass in that option (unnecessarily) to React-Redux v8.What's Changed
Show warning instead of throwing error that pure option has been removed
8.0.1
20 Apr 2022Add optional peer dependency on @types/react-dom
ts: Incorrect import of
SubscriptioncausesnoImplicitAnyerror
This release fixes an incorrect internal import of our
Subscriptiontype, which was causing TS compilation errors in some user projects. We've also listed@types/react-domas an optional peerDep. There are no runtime changes in this release.What's Changed
Add optional peer dependency on @types/react-dom
ts: Incorrect import of
SubscriptioncausesnoImplicitAnyerror
8.0.0
16 Apr 2022Integrate TypeScript port
Initial experimental React 18 compat prototyping
Fix compatibility with React 18 strict effects
This major version release updates
useSelector,connect, and<Provider>for compatibility with React 18, rewrites the React-Redux codebase to TypeScript (obsoleting use of@types/react-redux), modernizes build output, and removes the deprecatedconnectAdvancedAPI and thepureoption forconnect.npm i react-redux@latest yarn add react-redux@latest
Overview, Compatibility, and Migration
Our public API is still the same (
<Provider>,connectanduseSelector/useDispatch), but we've updated the internals to use the newuseSyncExternalStorehook from React. React-Redux v8 is still compatible with all versions of React that have hooks (16.8+, 17.x, and 18.x; React Native 0.59+), and should just work out of the box.In most cases, it's very likely that the only change you will need to make is bumping the package version to
"react-redux": "^8.0".If you are using the rarely-used
connectAdvancedAPI, you will need to rewrite your code to avoid that, likely by using the hooks API instead. Similarly, thepureoption forconnecthas been removed.If you are using Typescript, React-Redux is now written in TS and includes its own types. You should remove any dependencies on
@types/react-redux.While not directly tied to React-Redux, note that the recently updated
@types/react@18major version has changed component definitions to remove havingchildrenas a prop by default. This causes errors if you have multiple copies of@types/reactin your project. To fix this, tell your package manager to resolve@types/reactto a single version. Details:React issue #24304: React 18 types broken since release
Additionally, please see the React post on How to Ugprade to React 18 for details on how to migrate existing apps to correctly use React 18 and take advantage of its new features.
Changelog
React 18 Compatibility
React-Redux now requires the new
useSyncExternalStoreAPI in React 18. By default, it uses the "shim" package which backfills that API in earlier React versions, so React-Redux v8 is compatible with all React versions that have hooks (16.8+, and React Native 0.59+) as its acceptable peer dependencies.We'd especially like to thank the React team for their extensive support and cooperation during the
useSyncExternalStoredevelopment effort. They specifically designeduseSyncExternalStoreto support the needs and use cases of React-Redux, and we used React-Redux v8 as a testbed for howuseSyncExternalStorewould behave and what it needed to cover. This in turn helped ensure thatuseSyncExternalStorewould be useful and work correctly for other libraries in the ecosystem as well.Our performance benchmarks show parity with React-Redux v7.2.5 for both
connectanduseSelector, so we do not anticipate any meaningful performance regressions.useSyncExternalStoreand BundlingThe
useSyncExternalStoreshim is imported directly in the main entry point, so it's always included in bundles even if you're using React 18. This adds roughly 600 bytes minified to your bundle size.If you are using React 18 and would like to avoid that extra bundle cost, React-Redux now has a new
/nextentry point. This exports the exact same APIs, but directly importsuseSyncExternalStorefrom React itself, and thus avoids including the shim. You can alias"react-redux": "react-redux/next"in your bundler to use that instead.SSR and Hydration
React 18 introduces a new
hydrateRootmethod for hydrating the UI on the client in Server-Side Rendering usage. As part of that, theuseSyncExternalStoreAPI requires that we pass in an alternate state value other than what's in the actual Redux store, and that alternate value will be used for the entire initial hydration render to ensure the initial rehydrated UI is an exact match for what was rendered on the server. After the hydration render is complete, React will then apply any additional changes from the store state in a follow-up render.React-Redux v8 supports this by adding a new
serverStateprop for<Provider>. If you're using SSR, you should pass your serialized state to<Provider>to ensure there are no hydration mismatch errors:import { hydrateRoot } from 'react-dom/client' import { configureStore } from '@reduxjs/toolkit' import { Provider } from 'react-redux' const preloadedState = window.__PRELOADED_STATE__ const clientStore = configureStore({ reducer: rootReducer, preloadedState, }) hydrateRoot( document.getElementById('root'), <Provider store={clientStore} serverState={preloadedState}> <App /> </Provider> )TypeScript Migration and Support
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. This means that the
@types/react-reduxpackage is no longer needed, and you should remove that as a dependency.Note Please ensure that any installed copies of
reduxand@types/reactare de-duped. You are also encouraged to update to the latest versions of Redux Toolkit (1.8.1+) or Redux (4.1.2), to ensure consistency between installed types and avoid problems from types mismatches.We've tried to maintain the same external type signatures as much as possible. If you do see any compile problems, 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!
In addition to the "pre-typed"
TypedUseSelectorHook, there's now also aConnect<State = unknown>type that can be used as a "pre-typed" version ofconnectas well.As part of the process, we also updated the repo to use Yarn 3, copied the typetests files from DefinitelyTyped and expanded them, and improved our CI setup to test against multiple TS versions.
Removal of the
DefaultRootStatetypeThe
@types/react-reduxpackage, which has always been maintained by the community, included aDefaultRootStateinterface that was intended for use with TS's "module augmentation" capability. BothconnectanduseSelectorused this as a fallback if no state generic was provided. When we migrated React-Redux to TS, we copied over all of the types from that package as a starting point.However, the Redux team specifically considers use of a globally augmented state type to be an anti-pattern. Instead, we direct users to extract the
RootStateandAppDispatchtypes from the store setup, and create pre-typed versions of the React-Redux hooks for use in the app.Now that React-Redux itself is written in TS, we've opted to remove the
DefaultRootStatetype entirely. State generics now default tounknowninstead.Technically the module augmentation approach can still be done in userland, but we discourage this practice.
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/exportkeywords 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
connectAdvancedAPI 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
pureoption forconnect, which forced components to re-render regardless of whether props/state had actually changed if it was set tofalse. 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'suseSyncExternalStorestrictly requires immutable updates. So, we've removed thepureflag.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:
Integrate TypeScript port
Initial experimental React 18 compat prototyping
Fix compatibility with React 18 strict effects
Update to latest React 18 alpha dependencies
Port remaining v7 typetests and improve v8 types
Add initial SSR support for React 18 and React-Redux v8
Switch back to Subscription in useSelector to fix unsubscribe perf
Cleanup more code after
pureremovalSwap
useSyncExternalStoreshim behavior and update React depsRemove
DefaultRootStatetypeAdd SSR test for
serverStatebehaviorCleanup internal types in selectorFactory.ts
Remove ts-ignore for initMergeProps
Update peer deps for v8
Port DT fix for
dispatchProparg inmergePropsUpdate docs for v8 final
- 7.x
7.2.9
23 Sep 2022connect: Pass ownProps to areStatesEqual
This patch release updates the rarely-used
areStatesEqualoption forconnectto now pass throughownPropsfor additional use in determining which pieces of state to compare if desired.The new signature is:
{ areStatesEqual?: ( nextState: State, prevState: State, nextOwnProps: TOwnProps, prevOwnProps: TOwnProps ) => boolean }What's Changed
connect: Pass ownProps to areStatesEqual
7.2.8
1 Apr 2022This release fixes a bug in the 7.x branch that caused
<Provider>to unsubscribe and stop updating completely when used inside of React 18's<StrictMode>. The new "strict effects" behavior double-mounts components, and the subscription needed to be set up inside of auseLayoutEffectinstead of auseMemo. This was previously fixed as part of v8 development, and we've backported it.This release fixes a bug in the 7.x branch that caused
<Provider>to unsubscribe and stop updating completely when used inside of React 18's<StrictMode>. The new "strict effects" behavior double-mounts components, and the subscription needed to be set up inside of auseLayoutEffectinstead of auseMemo. This was previously fixed as part of v8 development, and we've backported it.Note: If you are now using React 18, we strongly recommend using the React-Redux v8 beta instead of v7.x!. v8 has been rewritten internally to work correctly with React 18's Concurrent Rendering capabilities. React-Redux v7 will run and generally work okay with existing code, but may have rendering issues if you start using Concurrent Rendering capabilities in your code.
Now that React 18 is out, we plan to finalize React-Redux v8 and release it live within the next couple weeks. Per an update yesterday in the "v8 roadmap" thread, React-Redux v8 will be updated in the next couple days to ensure support for React 16.8+ as part of the next beta release. We would really appreciate final feedback on using React-Redux v8 beta with React 18 before we publish the final version.
7.2.7
31 Mar 2022This release updates React-Redux v7's peer dependencies to accept React 18 as a valid version, only to avoid installation errors caused by NPM's "install all the peer deps and error if they don't match" behavior.
This release updates React-Redux v7's peer dependencies to accept React 18 as a valid version, only to avoid installation errors caused by NPM's "install all the peer deps and error if they don't match" behavior.
Note: If you are now using React 18, we strongly recommend using the React-Redux v8 beta instead of v7.x!. v8 has been rewritten internally to work correctly with React 18's Concurrent Rendering capabilities. React-Redux v7 will run and generally work okay with existing code, but may have rendering issues if you start using Concurrent Rendering capabilities in your code.
Now that React 18 is out, we plan to finalize React-Redux v8 and release it live within the next couple weeks. We would really appreciate final feedback on using React-Redux v8 beta with React 18 before we publish the final version.
7.2.5
4 Sep 2021Port entry point consolidation from 8.x branch (#1811 - @markerikson)
Update v7 branch to use Yarn v2 and improve CI process (#1810 - @markerikson)
Reduce unnecessary calls to useSelector selector (#1803 - @sufian-slack )
This release shrinks the size of our internal
Subscriptionclass, and updatesuseSelectorto avoid an unnecessary selector call on mount.Changes
Subscription Size Refactor
Our internal
Subscriptionimplementation 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.useSelectorMount OptimizationA user noticed that
useSelectorhad never been given an early "bail out if the root state is the same" check to match howconnectworks. 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.jsandalternate-renderers.jsentry 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
masterbranch 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.xbranch has also been updated to use Yarn v2 for consistency.These only affect contributors to the React-Redux package itself.
Changelog
Port entry point consolidation from 8.x branch (#1811 - @markerikson)
Update v7 branch to use Yarn v2 and improve CI process (#1810 - @markerikson)
Reduce unnecessary calls to useSelector selector (#1803 - @sufian-slack )
Port Subscription closure implementation from 8.x to 7.x (#1809 - @mbelsky)
7.2.4
24 Apr 2021This release drops our dependency on the core
reduxpackage by inliningbindActionCreators, and tweaksuseSelectorto ensure that selectors aren't run an extra time while re-rendering.Changelog
Redux Dependency Removal
React-Redux has always imported the
bindActionCreatorsutility from the corereduxpackage for use inconnect. However, that meant that we had to have a peer dependency onredux, and this was the only reason we actually required thatreduxbe installed. This became more annoying with the arrival of Redux Toolkit, which has its own dependency onreduxinternally, and thus users typically saw peer dependency warnings saying that "reduxisn'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
bindActionCreatorsdirectly 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>andconnectreally only need a Redux-store-compatible value to work right.useSelectorFixesUsers reported that
useSelectorwas re-running selector functions again unnecessarily while rendering after a dispatch. We've tweaked the logic to ensure that doesn't happen.useSelectoralso now has checks in development to ensure thatselectorandequalityFnare functions.Changes
7.2.3
23 Mar 2021Automatically install @types/react-redux as a dependency (#1699 - @markerikson )
Reuse latest selected state on selector re-run (#1654) (#1660 - @otakustay)
Use useIsomorphicLayoutEffect in Provider for consistency (#1683 - @speakingcode )
This release improves behavior in
useSelectorby returning the existing reference if the newly returned selector result passes the equality check, and adds a hard dependency on the@types/react-reduxpackage to ensure TS users always have the typedefs installed.Changes
useSelectorResults ReuseIssue #1654 reported that
useSelectorwas returning new references from a selector even if the equality comparison function returnedtrue. 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-reduxis annoying, and some users have gotten confused by that. This release adds a hard dependency on@types/react-redux, so that if you installreact-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:
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
Automatically install @types/react-redux as a dependency (#1699 - @markerikson )
Reuse latest selected state on selector re-run (#1654) (#1660 - @otakustay)
Use useIsomorphicLayoutEffect in Provider for consistency (#1683 - @speakingcode )
7.2.1
25 Jul 2020A potential race condition when dispatching actions from child components in the commit phase vs selecting data in a parent
Removed an excess new object creation when forcing a re-render
Our internal prop name for a forwarded ref is now
reactReduxForwardedRefto avoid a rare situation where someone else might be passing down a field namedforwardedRef
This release improves
useSelectorvalue display in the React DevTools, fixes a potential race condition, and fixes a couple additional minor issues.useSelectorDevTools DisplayThe React DevTools normally show custom hooks with their inspected name (such as "Selector" for
useSelector), and any calls to core hooks inside. This is not always informative, so React has theuseDebugValuehook to allow custom hooks to specify what value should be shown instead.useSelectornow callsuseDebugValueto specifically show the current selected value instead of its internal hooks usage.Bug Fixes
This release has a few different bug fixes:
A potential race condition when dispatching actions from child components in the commit phase vs selecting data in a parent
Removed an excess new object creation when forcing a re-render
Our internal prop name for a forwarded ref is now
reactReduxForwardedRefto avoid a rare situation where someone else might be passing down a field namedforwardedRefFixed a typo in a
useSelectorerror message
7.2.0
18 Feb 2020Fix memory leak issue with
UseEffect(@larrylin28 - #1506)Optimize createListenerCollection (@wurstbonbon - #1523)
This release fixes two bugs, an algorithmic problem with unsubscribing components and a memory leak with
connect. It also has optimizations for production bundle size, and adds a couple small improvements to developer readability while debugging.Bug Fixes
connectin v7 is implemented using hooks, and the hooks usage captures numerous values from the surrounding scope. We received a PR informing us that the way we were capturing these values would likely result in a copy of the first version of its props being kept alive indefinitely.This memory leak has been fixed by extracting a custom hook that receives all the necessary values as arguments, so that they're not captured via closure.
We also received a PR letting us know that the unsubscribe logic had a quadratic algorithm in it, as removing a subscriber would use an
indexOf(listener)check to remove that callback. If there were a large number of subscribers, that line's runtime would increase rapidly, causing slowdowns.This algorithm has been replaced with tracking subscribers via a linked list, which drastically improves the runtime of this section of the code even with large numbers of subscribers.
Bundle Size Improvements
We've made a number of small tweaks to the codebase to improve the ability of bundlers to shake and minimize the final included size in a bundle. The net result is that
react-redux@7.2.0is smaller than 7.1.3, dropping 1.3K min and 0.6K min+gzip. (In fact, it's even smaller than the pre-hooks 7.0.0 when gzipped!)Debugging Improvements
The
ReactReduxContextinstance now has adisplayNameset, so it should show up in the React DevTools asReactRedux.Provider.Also, when an error is caught in
useSelectorand re-thrown, we now append the original stack trace.Fix memory leak issue with
UseEffect(@larrylin28 - #1506)Optimize createListenerCollection (@wurstbonbon - #1523)
Rethrowing original errors thrown in selector functions (@Andarist - #1474)
Remove invariant in favor of doing NODE_ENV checks directly (@Andarist - #1472)
Wrap .propTypes and .displayName assignments with DEV check (@Andarist - #1471)
7.1.3
6 Nov 2019Remove leftover console statement (@markerikson - 30101bb)
Forgot to remove a
consolestatement before I published 7.1.2. Oops!Lint your source code before publishing, folks.
Remove leftover console statement (@markerikson - 30101bb)
7.1.2
6 Nov 2019Pass non-Redux-store values through the
storeprop (@markerikson - #1447)Fix RN batching and effect behavior (@markerikson - #1444)
Remove unused
latestStoreStatefield (@Hypnosphi - #1426)
This releases fixes a subtle timing bug with
connectanduseSelectorin React Native environments, and adds the ability to pass through non-Redux-store values as astoreprop.Fixed Store Subscriptions in React Native
Our current implementation requires cascading updates down through connected components. This is primarily done during React's "commit phase" via the
useLayoutEffecthook. Unfortunately, React warns whenuseLayoutEffectis called in SSR environments, so we try to feature-detect that and fall back touseEffectjust to avoid that warning.Unfortunately, a tweak to the feature detection conditions during the pre-7.1.0 work caused the check to accidentally fail in React Native environments. This meant that
useEffectwas actually being used all the time, and this led to occasional timing bugs such as #1313 and #1437 . This affected the previous v7.1.x releases.We've fixed that issue, and added additional test cases to ensure that our code works correctly under React Native.
See #1444 for more details on the feature detection and the fix.
Passing Through Non-Store Values
connecthas always accepted passing a Redux store directly to connected components as a prop namedstore(with the exception of v6). As a result, thestoreprop has effectively been treated as a "reserved" prop, in much the same way thatkeyandrefare "reserved" prop names handled by React.Some users may be using the word "store" to describe their domain data, and have asked to allow variables that aren't a Redux store through the
storeprop to the component (#1393). We've finally been able to implement that capability.Pass non-Redux-store values through the
storeprop (@markerikson - #1447)Fix RN batching and effect behavior (@markerikson - #1444)
Remove unused
latestStoreStatefield (@Hypnosphi - #1426)Mark the react renderers as optional peer deps. (@timdorr - 388d9e4)
Use the same condition for checking if SSR in useSelector.js as in connectAdvanced.js (@LeoDanielsson - #1419)
7.1.1
26 Aug 2019Add
create*Hookfactory APIsFree resources (free detached nodes from memory)
Convert Provider into function component with hooks
This release includes some new APIs for those that want to use a custom React Context with our Hooks API, a small memory optimization, and has a fix for when the
storechanges on aProviderwith incompatiblechildren.Add
create*Hookfactory APIsFree resources (free detached nodes from memory)
Convert Provider into function component with hooks
7.1.0
11 Jun 2019- removed
Remove
depsargument Add React Hooks
Add
depsargument touseSelector
After much discussion, we've decided these Hook things are probably going to stick around, so we might as well add some. Many thanks to @MrWolfZ, @josepot, @perrin4869, and @mpeyper for their contributions and to everyone else that offered feedback, ideas, and critiques as we built them out. Go open source!
Add React Hooks
Add
depsargument touseSelectorUse react-hooks-testing-library to test hooks
Remove
useReduxRemove
useActions- removed
Remove
depsargument Replace
shallowEqualwith reference equality inuseSelectorAvoid unnecessary selector evaluations
Minor Hook testing improvements
7.0.3
28 Apr 2019Fix timing issue in component updates due to consecutive dispatches
Lower react peer dependency to ^16.8.3
This release includes a bugfix for a timing issue in
connect(), and also lowers our React peer dependency slightly to allow better usage with React Native 0.59.Fix timing issue in component updates due to consecutive dispatches
Lower react peer dependency to ^16.8.3
7.0.2
12 Apr 2019Memoize renderedWrappedComponent separately
Fix timing issue with setting up store subscription inside a connected component
This is a bug fix release with a small performance improvement and fix for nested component unmounting.
Memoize renderedWrappedComponent separately
Fix timing issue with setting up store subscription inside a connected component
7.0.1
9 Apr 2019React-Redux version 7 resolves the performance issues that were reported with version 6, and lays the groundwork for us to design and ship a public
useRedux()-type Hooks API in a later 7.x release.React-Redux version 7 resolves the performance issues that were reported with version 6, and lays the groundwork for us to design and ship a public
useRedux()-type Hooks API in a later 7.x release.The major change for this release is that
connectis now implemented using Hooks internally. Because of this, we now require a minimum React version of 16.8.4 or higher.This release has undergone extensive performance benchmarking, and we're confident that it's the fastest version of React-Redux yet! We've also expanded our test suite to cover a number of additional use cases and scenarios.
npm install react-redux@latest
For discussion on the reasons for the major version change and the development process, see:
issue #1177 - React-Redux Roadmap: v6, Context, Subscriptions, and Hooks.
For discussion on the possible design of a future public hooks API, see:
issue #1179: Discussion: Potential hooks API design
Changes
This release should be public-API-compatible with version 6. The only public breaking change is the update of our React peer dependency from 16.4 to 16.8.4.
Note:
connectnow usesReact.memo()internally, which returns a special object rather than a function. Any code that assumed React components are only functions is wrong, and has been wrong since the release of React 16.6. If you were using PropTypes to check for valid component types, you should change fromPropTypes.functoPropTypes.elementTypeinstead.Internal Changes
Direct Component Subscriptions
In v6, we switched from individual components subscribing to the store, to having
<Provider>subscribe and components read the store state from React's Context API. This worked, but unfortunately the Context API isn't as optimized for frequent updates as we'd hoped, and our usage patterns led to some folks reporting performance issues in some scenarios.In v7, we've switched back to using direct subscriptions internally, which should improve performance considerably.
(This does result in some changes that are visible to user-facing code, in that updates dispatched in React lifecycle methods are immediately reflected in later component updates. Examples of this include components dispatching while mounting in an SSR environment. This was the behavior through v5, and is not considered part of our public API.)
Batched Updates
React has an
unstable_batchedUpdatesAPI that it uses to group together multiple updates from the same event loop tick. The React team encouraged us to use this, and we've updated our internal Redux subscription handling to leverage this API. This should also help improve performance, by cutting down on the number of distinct renders caused by a Redux store update.connectRewritten with HooksWe've reimplemented our
connectwrapper component to use hooks internally. While it may not be visible to you, it's nice to know we can take advantage of the latest React goodies!Public API Changes
Return of
storeas a PropWe've brought back the ability to pass a store as a prop directly to connected components. This was removed in version 6 due to internal implementation changes (components no longer subscribed to the store directly). Some users expressed concerns that working with context in unit tests was not sufficient. Since our components use direct subscriptions again, we've reimplemented this option, and that should resolve those concerns.
New
batchAPI for Batched React UpdatesReact's
unstable_batchedUpdate()API allows any React updates in an event loop tick to be batched together into a single render pass. React already uses this internally for its own event handler callbacks. This API is actually part of the renderer packages like ReactDOM and React Native, not the React core itself.Since React-Redux needs to work in both ReactDOM and React Native environments, we've taken care of importing this API from the correct renderer at build time for our own use. We also now re-export this function publicly ourselves, renamed to
batch(). You can use it to ensure that multiple actions dispatched outside of React only result in a single render update, like this:import { batch } from "react-redux"; function myThunk() { return (dispatch, getState) => { // should only result in one combined re-render, not two batch(() => { dispatch(increment()); dispatch(increment()); }) } }If you are using an alternative React renderer, like the Ink CLI renderer, that method isn't available for us to import. In that case, you will need to change your code to import from the new
react-redux/es/alternate-renderersentry point instead. (Usereact-redux/lib/alternate-renderersfor the CJS version). That entry point exports a no-op version ofbatch()that just executes the callback immediately, and does not provide React batching.In that situation, you may want to consider aliasing
react-reduxto one of those alternate entry points in your build tool for the best compatibility, especially if you're using any other libraries that depend on React-Redux.Note: v7.0.1 is identical code-wise to v7.0.0 . The extra patch release was to update the React requirement listed in the README.
7.0.0
9 Apr 2019Initial release, but we missed some updated docs. Ignore this 😄
- 6.x
6.0.1
20 Feb 2019Fix for circular component object structures, such as Emotion styled components.
Minor optimization: remove conditional
Ensure that component
contextprop really contains a React context
This is a minor release with support for react-hot-loader and a few small bug fixes for edge cases.
While you're here, please stop by #1177 to see our roadmap for the next versions of React Redux. We are aware that performance is not so hot in 6.0. Short version: We put too much traffic on React's context API, which isn't really designed for high levels of reads and writes. We're looking to reduce that load and get performance back on track in a minor release, so there won't be backwards compatibility concerns. We have a new extensive benchmark suite to keep us on track and ensure we're not regressing on speed in the future.
And yes, we know about Hooks. Check out #1179.
Fix for circular component object structures, such as Emotion styled components.
Minor optimization: remove conditional
Ensure that component
contextprop really contains a React contextreact-hot-loader compatibility (#1168/#1137
Upgrade to react-is v16.7.0
6.0.0
5 Dec 2018- breaking
The
withRefoption toconnecthas been replaced withforwardRef. If{forwardRef : true}has been passed toconnect, adding a ref to the connected wrapper component will actually return the instance of the wrapped component. - breaking
Passing
storeas a prop to a connected component is no longer supported. Instead, you may pass a customcontext={MyContext}prop to both<Provider>and<ConnectedComponent>. You may also pass{context : MyContext}as an option toconnect. Use React.createContext()
🎉 This is our first big release supporting the new Context API added in React 16.4!
As such, we now require React 16.4 or higher. Make sure to update your version when updating to this release.
This work has been mostly lead
Note: If you'd like to know more about the changes in v6, and how the implementation has changed over time, see Mark's post Idiomatic Redux: The History and Implementation of React-Redux.
Breaking Changes
- breaking
The
withRefoption toconnecthas been replaced withforwardRef. If{forwardRef : true}has been passed toconnect, adding a ref to the connected wrapper component will actually return the instance of the wrapped component. - breaking
Passing
storeas a prop to a connected component is no longer supported. Instead, you may pass a customcontext={MyContext}prop to both<Provider>and<ConnectedComponent>. You may also pass{context : MyContext}as an option toconnect.
Behavior Changes
Any library that attempts to access the store instance out of legacy context will break, because we now put the store state into a
<Context.Provider>instead. Examples of this includeconnected-react-routerandreact-redux-subspace. (The current implementation does also put the store itself into that same context. While accessing the store in context is not part of our public API, we will still try to make it possible for other libraries to access it, with the understanding that this could break at any time.)Also, there is a behavior change around dispatching actions in constructors /
componentWillMount. Previously, dispatching in a parent component's constructor would cause its children to immediately use the updated state as they mounted, because each component read from the store individually. In version 6, all components read the same current store state value from context, which means the tree will be consistent and not have "tearing". This is an improvement overall, but there may be applications that relied on the existing behavior.Use React.createContext()
Use Prettier
Only run isValidElementType in development builds
Treat
nullas a valid plain object prototype inisPlainObject()Ensure connectAdvanced only re-renders if derived props change
- 5.x
5.1.2
8 Oct 2019Bump up hoist-non-react-statics version
Avoid warnings in React >=16.3
Use UNSAFE_ lifecycle event names where supported
5.1.1
10 Nov 2018Upgrade hoist-non-react-statics to deal with contextType
Treat
nullas a valid plain object prototype inisPlainObject()
5.1.0
25 Oct 2018Simplify object check and eliminate lodash dependency
Remove subkey arg
Switch our test suite to Jest
The biggest fix is for
connect()being used with React's newerforwardRef,memo, andlazyAPIs.We also have begun a complete rewrite of our docs for React Redux. Check them out! Many thanks to those who contributed: @markerikson, @sveinpg, @wgao19, @BTMPL, @pyliaorachel, @dagstuan, @Kerumen, and @carloluis (sorry if I forgot someone!). Docs are a great way to get started contributing to open source, so open a PR today! Check #1001 to see what else needs to be done.
We're also looking at overhauling Redux's documentation. Check out reduxjs/redux#2590 for the latest there.
Simplify object check and eliminate lodash dependency
Remove subkey arg
Switch our test suite to Jest
Implement testing in React 0.14, 15, and 16.x
Convert tests to use react-testing-library instead of Enzyme
Add unpkg field to package.json
Set up basic docusaurus structure
Add nodejs version 10 for ci
5.0.6
8 Aug 2017Persist child listeners through hot reload
Move ref context binding to fix object freezing middleware
Remove explicit Provider.displayName in favor of the inferred name
Persist child listeners through hot reload
Move ref context binding to fix object freezing middleware
Remove explicit Provider.displayName in favor of the inferred name
Move create-react-class back to devDependencies
Switch build process back to npm@5
5.0.4
9 Apr 2017Fix deprecation warnings with React 15.5.0