You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/migrations/1.x-to-2.x.md
+41-35Lines changed: 41 additions & 35 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
-
id: 1.x-to-2.x
3
-
title: 1.x → 2.x
4
-
sidebar_label: 1.x → 2.x
2
+
id: migrating-1.x-to-2.x
3
+
title: Migrating 1.x → 2.x
4
+
sidebar_label: Migrating 1.x → 2.x
5
5
hide_title: true
6
6
toc_max_heading_level: 4
7
7
---
@@ -10,33 +10,31 @@ toc_max_heading_level: 4
10
10
11
11
<divclassName="migration-guide">
12
12
13
-
# 1.x → 2.x
13
+
# Migrating 1.x → 2.x
14
14
15
15
## Introduction
16
16
17
-
<!-- TODO: some blurb here about how cool 2.0 is -->
17
+
Redux Toolkit has been available since 2019, and today it's the standard way to write Redux apps. We've gone 4+ years without any breaking changes. Now, RTK 2.0 gives us a chance to modernize the packaging, clean up deprecated options, and tighten up some edge cases.
18
18
19
-
## Breaking Changes
20
-
21
-
### Core, Toolkit and React Redux
22
-
23
-
#### Action types _must_ be strings
19
+
Redux Toolkit 2.0 is accompanied by major versions of all the other Redux packages: Redux core 5.0, React-Redux 9.0, Redux Thunk 3.0, and Reselect 5.0.
24
20
25
-
We've always specifically told our users that [actions and state _must_ be serializable](https://redux.js.org/style-guide/#do-not-put-non-serializable-values-in-state-or-actions), and that `action.type`_should_ be a string. This is both to ensure that actions are serializable, and to help provide a readable action history in the Redux DevTools.
21
+
This page lists known potentially breaking changes in Redux Toolkit 2.0 and Redux core 5.0, as well as new features in Redux Toolkit 2.0. As a reminder, you should not need to actually install or use the core `redux` package directly - RTK wraps that, and re-exports all methods and types.
26
22
27
-
`store.dispatch(action)` now specifically enforces that `action.type`_must_ be a string and will throw an error if not, in the same way it throws an error if the action is not a plain object.
23
+
In practice, **most of the "breaking" changes should not have an actual effect on end users**. The changes most likely to need app code updates are:
28
24
29
-
In practice, this was already true 99.99% of the time and shouldn't have any effect on users (especially those using Redux Toolkit and `createSlice`), but there may be some legacy Redux codebases that opted to use Symbols as action types.
25
+
-[Object syntax removed for `createReducer` and `createSlice.extraReducers`](#object-syntax-for-createsliceextrareducers-and-createreducer-removed)
26
+
-[`configureStore.middleware` must be a callback](#configurestoremiddleware-must-be-a-callback)
27
+
-[`Middleware` type changed - Middleware `action` and `next` are typed as `unknown`](#middleware-type-changed---middleware-action-and-next-are-typed-as-unknown)
30
28
31
-
#### Dropping UMD builds
29
+
##Packaging Changes (all)
32
30
33
-
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.
31
+
We've made updates to the build packaging for all of the Redux-related libraries. These are technically "breaking", but _should_ be transparent to end users, and actually enable better support for scenarios such as using Redux via ESM files under Node.
34
32
35
-
For now, we're dropping those build artifacts from the published package, on the grounds that the use cases seem pretty rare today.
33
+
#### Addition of `exports` field in `package.json`
36
34
37
-
We do have a browser-ready ESM build artifact included at dist/redux.browser.mjs, which can be loaded via a script tag that points to that file on Unpkg.
35
+
We've migrated the package definitions to include the `exports` field for defining which artifacts to load, with a modern ESM build as the primary artifact (with CJS still included for compatibility purposes).
38
36
39
-
If you have strong use cases for us continuing to include UMD build artifacts, please let us know!
37
+
We've done local testing of the package, but we ask the community to try out this in your own projects and report any breakages you find!
40
38
41
39
#### Build Artifact Modernization
42
40
@@ -46,23 +44,27 @@ We've updated the build output in several ways:
46
44
- Moved all build artifacts to live under ./dist/, instead of separate top-level folders
47
45
- The lowest Typescript version we test against is now 4.7
48
46
49
-
#### Addition of `exports` field in `package.json`
47
+
#### Dropping UMD builds
48
+
49
+
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.
50
50
51
-
We've migrated the package definitions to be a full `{type: "module"}` ESM package with an `exports` field (with CJS still included for compatibility purposes).
51
+
For now, we're dropping those build artifacts from the published package, on the grounds that the use cases seem pretty rare today.
52
52
53
-
We've done local testing of the package, but we ask the community to try out this in your own projects and report any breakages you find!
53
+
We do have a browser-ready ESM build artifact included at `dist/$PACKAGE_NAME.browser.mjs`, which can be loaded via a script tag that points to that file on Unpkg.
54
54
55
-
#### Error message extraction
55
+
If you have strong use cases for us continuing to include UMD build artifacts, please let us know!
56
56
57
-
Redux 4.1.0 optimized its bundle size by [extracting error message strings out of production builds](https://github.com/reduxjs/redux/releases/tag/v4.1.0), 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).
57
+
## Breaking Changes
58
+
59
+
### Core
58
60
59
-
#### Internal listener implementation
61
+
#### Action types _must_ be strings
60
62
61
-
The Redux store has always used an array to track listener callbacks, and used `listeners.findIndex` to remove listeners on unsubscribe. As we found in React Redux, that can have perf issues when many listeners are unsubscribing at once.
63
+
We've always specifically told our users that [actions and state _must_ be serializable](https://redux.js.org/style-guide/#do-not-put-non-serializable-values-in-state-or-actions), and that `action.type`_should_ be a string. This is both to ensure that actions are serializable, and to help provide a readable action history in the Redux DevTools.
62
64
63
-
In React Redux, we fixed that with a more sophisticated linked list approach. Here, we've updated the listeners to be stored in a `Map` instead, which has better delete performance than an array.
65
+
`store.dispatch(action)` now specifically enforces that `action.type`_must_ be a string and will throw an error if not, in the same way it throws an error if the action is not a plain object.
64
66
65
-
In practice this shouldn't have any real effect, because React Redux sets up a subscription in `<Provider>`, and all nested components subscribe to that. But, nice to fix it here as well.
67
+
In practice, this was already true 99.99% of the time and shouldn't have any effect on users (especially those using Redux Toolkit and `createSlice`), but there may be some legacy Redux codebases that opted to use Symbols as action types.
66
68
67
69
<divclass="typescript-only">
68
70
@@ -72,7 +74,7 @@ In 2019, we began a community-powered conversion of the Redux codebase to TypeSc
72
74
73
75
However, the TS-converted code in master has sat around since then, unused and unpublished, due to concerns about possible compatibility issues with the existing ecosystem (as well as general inertia on our part).
74
76
75
-
Redux core v5 is now built from that converted source code. In theory, this should be almost identical in both runtime behavior and types to the 4.x build, but it's very likely that some of the changes may cause types issues.
77
+
Redux core v5 is now built from that TS-converted source code. In theory, this should be almost identical in both runtime behavior and types to the 4.x build, but it's very likely that some of the changes may cause types issues.
76
78
77
79
Please report any unexpected compatibility issues on [Github](https://github.com/reduxjs/redux/issues)!
Redux 4.1.0 optimized its bundle size by [extracting error message strings out of production builds](https://github.com/reduxjs/redux/releases/tag/v4.1.0), 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).
313
+
308
314
<divclass="typescript-only">
309
315
310
316
#### Non-default middleware/enhancers must use `Tuple`
@@ -338,9 +344,9 @@ If you prefer to assume that the lookups _might_ be undefined, use TypeScript's
338
344
339
345
</div>
340
346
341
-
## Features
347
+
## New Features
342
348
343
-
<!-- TODO: some blurb here about how new features are only in toolkit(?) -->
349
+
These features are new in Redux Toolkit 2.0, and help cover additional use cases that we've seen users ask for in the ecosystem.
344
350
345
351
### `combineSlices` API with slice reducer injection for code-splitting
### `createSlice.reducers` callback syntax and thunk support
449
455
450
456
One of the oldest feature requests we've had is the ability to declare thunks directly inside of `createSlice`. Until now, you've always had to declare them separately, give the thunk a string action prefix, and handle the actions via `createSlice.extraReducers`:
451
457
@@ -484,9 +490,9 @@ We've _wanted_ to include a way to define thunks directly inside of `createSlice
484
490
485
491
We've settled on these compromises:
486
492
493
+
-**In order to create async thunks with `createSlice`, you specifically need to [set up a custom version of `createSlice` that has access to `createAsyncThunk`](../api/createSlice#createasyncthunk)**.
487
494
- You can declare thunks inside of `createSlice.reducers`, by using a "creator callback" syntax for the `reducers` field that is similar to the `build` callback syntax in RTK Query's `createApi` (using typed functions to create fields in an object). Doing this does look a bit different than the existing "object" syntax for the `reducers` field, but is still fairly similar.
488
495
- You can customize _some_ of the types for thunks inside of `createSlice`, but you _cannot_ customize the `state` or `dispatch` types. If those are needed, you can manually do an `as` cast, like `getState() as RootState`.
489
-
- In order to create async thunks with `createSlice`, you specifically need to [set up a version that uses `createAsyncThunk`](../api/createSlice#createasyncthunk).
490
496
491
497
In practice, we hope these are reasonable tradeoffs. Creating thunks inside of `createSlice` has been widely asked for, so we think it's an API that will see usage. If the TS customization options are a limitation, you can still declare thunks outside of `createSlice` as always, and most async thunks don't need `dispatch` or `getState` - they just fetch data and return. And finally, setting up a custom `createSlice` allows you to opt into `createAsyncThunk` being included in your bundle size (though it may already be included if used directly or as part of RTK Query - in either of these cases there's no _additional_ bundle size).
Using the new callback syntax is entirely optional (the object syntax is still standard), but an existing slice would need to be converted before it can take advantage of the new capabilities this syntax provides. To make this easier, a [codemod](../api/codemods) is provided.
563
+
**Using the new callback syntax is entirely optional (the object syntax is still standard)**, but an existing slice would need to be converted before it can take advantage of the new capabilities this syntax provides. To make this easier, a [codemod](../api/codemods) is provided.
@@ -593,7 +599,7 @@ We've updated `configureStore` to add the `autoBatchEnhancer` to the store setup
593
599
594
600
[`entityAdapter.getSelectors()`](../api/createEntityAdapter#selector-functions) now accepts an options object as its second argument. This allows you to pass in your own preferred `createSelector` method, which will be used to memoize the generated selectors. This could be useful if you want to use one of Reselect's new alternate memoizers, or some other memoization library with an equivalent signature.
595
601
596
-
### New dev checks in `reselect` v5
602
+
### New dev checks in Reselect v5
597
603
598
604
Reselect v5 includes a dev-only check to check stability of input selectors, by running them an extra time with the same parameters, and checking that the result matches.
With `reselect`'s default cache size of 1, this can cause caching issues if called in multiple components with different arguments. One typical solution for this (without `createSlice`) is a [selector factory](https://redux.js.org/usage/deriving-data-selectors#creating-unique-selector-instances):
800
+
With `createSelector`'s default cache size of 1, this can cause caching issues if called in multiple components with different arguments. One typical solution for this (without `createSlice`) is a [selector factory](https://redux.js.org/usage/deriving-data-selectors#creating-unique-selector-instances):
0 commit comments