Skip to content

Releases: reduxjs/redux-toolkit

v2.0.0-rc.3

02 Dec 04:20

Choose a tag to compare

v2.0.0-rc.3 Pre-release
Pre-release

This release candidate updates to the latest Reselect 5.0 RC to pick up the rename of defaultMemoize to lruMemoize.

Note that we hope to release Redux Toolkit 2.0, Redux core 5.0, and React-Redux 9.0 by this weekend!

See the preview Redux Toolkit 2.0 + Redux core 5.0 Migration Guide for an overview of breaking changes in RTK 2.0 and Redux core.

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

npm install @reduxjs/toolkit@next

yarn add @reduxjs/toolkit@next

Changelog

RTK Query Selector Usage Fixes

The previous v2.0.0-rc.2 release picked up Reselect's dev mode checks for result functions that just return their input, like x => x. Turns out that some of RTK Query's internal selector usage did that in some cases :) That resulted in a ton of warnings being printed. We've updated our internals to fix that.

Reselect Changes

The Reselect defaultMemoize function has now been renamed to lruMemoize, since it's no longer the default. See the Reselect v5.0.0-rc.1 release notes for more details.

What's Changed

Full Changelog: v2.0.0-rc.2...v2.0.0-rc.3

v2.0.0-rc.2

01 Dec 05:02

Choose a tag to compare

v2.0.0-rc.2 Pre-release
Pre-release

This release candidate updates to the latest Reselect 5.0 RC to pick up the change to use weakMapMemoize as the default inside createSelector.

Note that we hope to release Redux Toolkit 2.0, Redux core 5.0, and React-Redux 9.0 by the start of December! (If we don't hit that, we'll aim for January, after the holidays.)

See the preview Redux Toolkit 2.0 + Redux core 5.0 Migration Guide for an overview of breaking changes in RTK 2.0 and Redux core.

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

npm install @reduxjs/toolkit@next

yarn add @reduxjs/toolkit@next

Changelog

Reselect Changes

Reselect v5.0.0-rc.0 makes the breaking change to use weakMapMemoize as the default memoization implementation for createSelector. This memoizer has an effectively infinite cache size, which should cut down on the number of recalculations in a typical app, and help improve performance overall. This is a breaking change, but one that should be invisible to most users.

It also adds a new dev-mode check for result functions that look like x => x, which is almost always a mistake.

See the Reselect v5.0.0-rc.0 release notes for more details.

What's Changed

  • Bump Reselect to 5.0.0-rc.0 to pick up weakMapMemoize change by @markerikson in #3928

Full Changelog: v2.0.0-rc.1...v2.0.0-rc.2

v2.0.0-rc.1

24 Nov 17:05

Choose a tag to compare

v2.0.0-rc.1 Pre-release
Pre-release

This release candidate updates to the latest Redux 5.0 RC to use its exported isAction and isPlainObject util methods, renames the pre-minified ESM production build to redux-toolkit.browser.mjs and drops the ESM precompiled dev build, and updates build tooling.

Note that we hope to release Redux Toolkit 2.0, Redux core 5.0, and React-Redux 9.0 by the start of December! (If we don't hit that, we'll aim for January, after the holidays.)

See the preview Redux Toolkit 2.0 + Redux core 5.0 Migration Guide for an overview of breaking changes in RTK 2.0 and Redux core.

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

npm install @reduxjs/toolkit@next

yarn add @reduxjs/toolkit@next

Changelog

isAction Predicate

We recently added an isAction predicate to RTK, then realized it's better suited for the Redux core. This can be used anywhere you have a value that could be a Redux action object, and you need to check if it is actually an action. This is specifically useful for use with the updated Redux middleware TS types, where the default value is now unknown and you need to use a type guard to tell TS that the current value is actually an action.

This is now exported from the Redux core, and re-exported from RTK, which also uses it internally to avoid duplicating that logic.

We've also exported the isPlainObject util that's been in the Redux codebase for years as well.

ESM Build Artifacts

We previously dropped the UMD build artifacts in an earlier alpha, but added ESM build artifacts that are pre-compiled to remove the process.env.NODE_ENV definitions, with the intent that these are useable as <script type="module"> tags in the browser. Those were previously named as redux-toolkit.modern.development.mjs and redux-toolkit.modern.production.mjs.

We've renamed the production artifact to redux-toolkit.browser.mjs to be consistent with the other Redux-related packages, and removed the dev build artifact on the grounds that we don't think there's enough likely usage to include it. If you think you would specifically benefit from having an ESM browser-compatible dev artifact, let us know!

What's Changed

Full Changelog: v2.0.0-rc.0...v2.0.0-rc.1

v2.0.0-rc.0

17 Nov 03:50

Choose a tag to compare

v2.0.0-rc.0 Pre-release
Pre-release

This release candidate modifies the approach for defining async thunks inside of createSlice, and improves several bits of usage and implementation around selectors.

Note that we hope to release Redux Toolkit 2.0, Redux core 5.0, and React-Redux 9.0 by the start of December! (If we don't hit that, we'll aim for January, after the holidays.)

See the preview Redux Toolkit 2.0 + Redux core 5.0 Migration Guide for an overview of breaking changes in RTK 2.0 and Redux core.

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

npm install @reduxjs/toolkit@next

yarn add @reduxjs/toolkit@next

Changelog

Async Thunk and createSlice changes

In earlier alphas, we added the ability to define async thunks directly inside of createSlice.reducers, using a callback syntax. However, that meant that createSlice had a hard dependency on createAsyncThunk, and importing createSlice would always include createAsyncThunk in an app bundle even if it wasn't being used.

In practice, we expect that most RTK users will use createAsyncThunk, either directly or as part of RTK Query. But, we take bundle size seriously, and didn't want to force all uses of createSlice to add the 2K for createAsyncThunk to a bundle if it isn't actually being used.

Since we expect that defining thunks inside of createSlice is a less-common use case, we've settled on a compromise. The standard createSlice method does not support calling create.asyncThunk() inside even if you use the callback syntax. Instead, you need to call buildCreateSlice() to create a customized version of createSlice with the async thunk capabilities built in, and use that:

const createSliceWithThunks = buildCreateSlice({
  creators: { asyncThunk: asyncThunkCreator },
})

const todosSlice = createSliceWithThunks ({
  name: 'todos',
  initialState: {
    loading: false,
    todos: [],
    error: null,
  } as TodoState,
  reducers: (create) => ({
    // A normal "case reducer", same as always
    deleteTodo: create.reducer((state, action: PayloadAction<number>) => {
      state.todos.splice(action.payload, 1)
    }),
    // A case reducer with a "prepare callback" to customize the action
    addTodo: create.preparedReducer(
      (text: string) => {
        const id = nanoid()
        return { payload: { id, text } }
      },
      // action type is inferred from prepare callback
      (state, action) => {
        state.todos.push(action.payload)
      }
    ),
    // An async thunk
    fetchTodo: create.asyncThunk(
      // Async payload function as the first argument
      async (id: string, thunkApi) => {
        const res = await fetch(`myApi/todos?id=${id}`)
        return (await res.json()) as Item
      },
      // An object containing `{pending?, rejected?, fulfilled?, settled?, options?}` second
      {
        pending: (state) => {
          state.loading = true
        },
        rejected: (state, action) => {
          state.error = action.payload ?? action.error
        },
        fulfilled: (state, action) => {
          state.todos.push(action.payload)
        },
        // settled is called for both rejected and fulfilled actions
        settled: (state, action) => {
          state.loading = false
        },
      }
    ),
  }),
})

Selector Changes

createSlice now adds a selectSlice field to all slice objects. This simple selector assumes that the slice has been added at rootState[slice.name] (or rootState[slice.reducerPath] if defined). This is useful for basic lookups of the slice's state.

entityAdapter.getSelectors() now accepts alternate selector creators with customized memoization options.

What's Changed

  • [RTK v2.0] output selector fields are currently missing in selector functions created using createDraftSafeSelector. by @aryaemami59 in #3722
  • createDynamicMiddleware bike shedding by @EskiMojo14 in #3763
  • Allow passing selector creators with different memoize options to getSelectors by @EskiMojo14 in #3833
  • Add selectSlice to slice instance by @EskiMojo14 in #3838
  • Throw an error if ApiProvider is nested inside a normal Provider. by @EskiMojo14 in #3855
  • Create standardised methods of modifying reducer handler context. by @EskiMojo14 in #3872
  • Require calling buildCreateSlice to use create.asyncThunk by @EskiMojo14 in #3867
  • Restore the toString override, but keep it out of the docs. by @EskiMojo14 in #3877
  • Selector housekeeping - emplace and unwrapped by @EskiMojo14 in #3878
  • Update deps for RC by @markerikson in #3883

Full Changelog: v2.0.0-beta.4...v2.0.0-rc.0

v2.0.0-beta.4

28 Oct 23:34

Choose a tag to compare

v2.0.0-beta.4 Pre-release
Pre-release

This beta release updates RTK Query to fix issues around cache entry behavior when subscription: false is used or with multiple lazy queries in progress, alters RTK Query's tag invalidation behavior to better handle cases where multiple invalidations may happen in sequence, rewrites RTK Query's internals to improve performance around subscription data syncing, and updates Reselect to the latest 5.0.0-beta.0.

npm i @reduxjs/toolkit@beta

yarn add @reduxjs/toolkit@beta

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

Changelog

RTK Query Behavior Changes

We've had a number of reports where RTK Query had issues around usage of dispatch(endpoint.initiate(arg, {subscription: false})). There were also reports that multiple triggered lazy queries were resolving the promises at the wrong time. Both of these had the same underlying issue, which was that RTKQ wasn't tracking cache entries in these cases (intentionally). We've reworked the logic to always track cache entries (and remove them as needed), which should resolve those behavior issues.

We also have had issues raised about trying to run multiple mutations in a row and how tag invalidation behaves. RTKQ now has internal logic to delay tag invalidation briefly, to allow multiple invalidations to get handled together. This is controlled by a new invalidationBehavior: 'immediate' | 'delayed' flag on createApi. The new default behavior is 'delayed'. Set it to 'immediate' to revert to the behavior in RTK 1.9.

In RTK 1.9, we reworked RTK Query's internals to keep most of the subscription status inside the RTKQ middleware. The values are still synced to the Redux store state, but this is primarily for display by the Redux DevTools "RTK Query" panel. Related to the cache entry changes above, we've optimized how often those values get synced to the Redux state for perf.

Other Changes

We've updated the Reselect dependency to Reselect 5.0.0-beta.0, which adds the ability to pass memoizer functions and options directly to createSelector.

The new create.asyncThunk() builder inside of createSlice can now be given a settled reducer, which will run when the thunk promise either fulfills or rejects.

What's Changed

Full Changelog: v2.0.0-beta.3...v2.0.0-beta.4

v2.0.0-beta.3

12 Oct 00:09

Choose a tag to compare

v2.0.0-beta.3 Pre-release
Pre-release

This beta release updates configureStore to remove the deprecated option of passing an array for middleware, improves the createEntityAdapter types to improve compatibility, updates deps to use the latest React-Redux beta, and optimizes the TS compile perf for RTKQ hooks.

npm i @reduxjs/toolkit@beta

yarn add @reduxjs/toolkit@beta

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

Changelog

configureStore.middleware Option Must Be A Callback

Since the beginning, configureStore has accepted a direct array value as the middleware option. However, providing an array directly prevents configureStore from calling getDefaultMiddleware(). So, middleware: [myMiddleware]` means there is no thunk middleware added (or any of the dev-mode checks).

This is a footgun, and we've had numerous users accidentally do this and cause their apps to fail because the default middleware never got configured.

We already had made the enhancers option only accept the callback form, so we've done the same thing for middleware.

If for some reason you still want to replace all of the built-in middleware, do so by returning an array from the callback:

const store = configureStore({
  reducer,
  middleware: (getDefaultMiddleware) => {
    // WARNING: this means that _none_ of the default middleware are added!
    return [myMiddleware];
    // or for correct TS inference, use:
    // return new Tuple(myMiddleware)
  }
})

But note that we consistently recommend not replacing the default middleware entirely, and that you should use return getDefaultMiddleware().concat(myMiddleware).

TS Updates

The types for createEntityAdapter have been reworked for better compat with Immer drafts.

The RTK Query types for generating React hooks have been optimized for much faster TS compilation perf (~60% improvement in one synthetic example app).

Other Changes

RTK Query's custom React hooks option now checks at runtime that all 3 hooks have been provided.

A new codemod is now available as part of the @reduxjs/rtk-codemods package that will convert a given createSlice call to the new "create callback" notation, which is primarily used for adding thunks inside of createSlice. Unlike the other codemods for replacing the obsolete/removed object syntax in createReducer and createSlice, this is purely optional.

What's Changed

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

v1.9.7

04 Oct 22:01

Choose a tag to compare

This bugfix release rewrites the RTKQ hook TS types to significantly improve TS perf.

Changelog

RTKQ TS Perf

A number of users had reported that Intellisense for RTKQ API objects was extremely slow (multiple seconds) - see discussion in #3214 . We did some perf investigation on user-provided examples, and concluded that the biggest factor to slow RTKQ TS perf was the calculation of hook names like useGetPokemonQuery, which was generating a large TS union of types.

We've rewritten that hook names type calculation to use mapped types and a couple of intersections. In a specific user-provided stress test repo, it dropped TS calculation time by 60% (2600ms to 1000ms).

There's more potential work we can do to improve things, but this seems like a major perf improvement worth shipping now.

What's Changed

Full Changelog: v1.9.6...v1.9.7

v2.0.0-beta.2

25 Sep 00:24

Choose a tag to compare

v2.0.0-beta.2 Pre-release
Pre-release

This beta release updates the build step to extract error messages and optimizes internal imports in RTK Query for smaller production bundle sizes, adds a selectCachedArgsForQuery util, and includes all changes in v1.9.6

npm i @reduxjs/toolkit@beta

yarn add @reduxjs/toolkit@beta

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

Changelog

Bundle Size Optimizations

Redux 4.1.0 optimized its bundle size by extracting error message strings out of production builds, based on React's approach. We've applied the same technique to RTK. This saves about 1000 bytes from prod bundles (actual benefits will depend on which imports are being used).

We also noted that ESBuild does not deduplicate imports when it bundles source files, and this was causing RTK Query's bundle to contain a dozen references to import { } from "@reduxjs/toolkit", including some of the same methods. Manually deduplicating those saves about 600 bytes off the production RTKQ artifact.

Other Changes

We've added a selectCachedArgsForQuery util selector that will return the saved arguments that were used for a given cache entry.

This also includes all of the changes in v1.9.6.

What's Changed

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

v1.9.6

24 Sep 23:47

Choose a tag to compare

This bugfix release adds a new dev-mode middleware to catch accidentally dispatching an action creator, adds a new listener middleware option around waiting for forks, adds a new option to update provided tags when updateQueryData is used, reworks internal types to better handle uses with TS declaration output, and fixes a variety of small issues.

Changelog

Action Creator Dev Check Middleware

RTK already includes dev-mode middleware that check for the common mistakes of accidentally mutating state and putting non-serializable values into state or actions.

Over the years we've also seen a semi-frequent error where users accidentally pass an action creator reference to dispatch, instead of calling it and dispatching the action it returns.

We've added another dev-mode middleware that specifically catches this error and warns about it.

Additional Options

The listener middleware's listenerApi.fork() method now has an optional autoJoin flag that can be used to keep the effect from finishing until all active forked tasks have completed.

updateQueryData now has an updateProvidedTags option that will force a recalculation of that endpoint's provided tags. It currently defaults to false, and we'll likely turn that to true in the next major.

Other Fixes

The builder.addCase method now throws an error if a type string is empty.

fetchBaseQuery now uses an alternate method to clone the original Request in order to work around an obscure Chrome bug.

The immutability middleware logic was tweaked to avoid a potential stack overflow.

Types Changes

The internal type imports have been reworked to try to fix "type portability" issues when used in combination with TS declaration outputs.

A couple additional types were exported to help with wrapping createAsyncThunk.

What's Changed

Full Changelog: v1.9.5...v1.9.6

v2.0.0-beta.1

26 Aug 22:59

Choose a tag to compare

v2.0.0-beta.1 Pre-release
Pre-release

This beta release updates the build and packaging setup to improve TS and ESM compatibility, fixes several TS issues, and updates to the latest React-Redux and Redux-Thunk deps.

npm i @reduxjs/toolkit@beta

yarn add @reduxjs/toolkit@beta

The 2.0 integration branch contains the docs preview for the 2.0 changes. Not all changes are documented yet, but you can see API reference pages for most of the new features here:

Build and TS Updates

We've made several tweaks to the packaging to improve compatibility for ESM and TS typedef definitions, which should fix some issues that were reported with beta.0.

We also fixed several assorted TS issues that were affecting users in specific edge cases.

Other Changes

We removed the AbortController polyfill from createAsyncThunk, saving some bytes.

We've updated deps to [email protected] and [email protected].

What's Changed

Full Changelog: v2.0.0-beta.0...v2.0.0-beta.1