reduxjs/redux-toolkit
### [`v1.8.5`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.5)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.4...v1.8.5)
This bugfix releas fixes an issue with large `keepUnusedDataFor` values overflowing JS timers, exports the types for the Redux DevTools Extension option, and and improves behavior of URL string generation.
#### Changelog
##### `keepUnusedDataFor` Timer Fix
`keepUnusedDataFor` accepts a value in seconds. When there are no more active subscriptions for a piece of data, RTKQ will set a timer using `setTimeout`, and `keepUnusedDataFor * 1000` as the timer value.
We've been advising users that if they want to keep data in the cache forever that they should use a very large value for `keepUnusedDataFor`, such as 10 years in seconds.
However, it turns out that JS engines use a 32-bit signed int for timers, and 32-bits in milliseconds is only 24.8 days. If a timer is given a value larger than that, it triggers immediately.
We've updated the internal logic to clamp the `keepUnusedDataFor` value to be between 0 and `THIRTY_TWO_BIT_MAX_TIMER_SECONDS - 1`.
Note that in RTK 1.9 (coming soon), RTKQ will also accept `Infinity` as a special `keepUnusedDataFor` value to indicate cached data should never be expired.
##### Other Changes
RTK inlines the TS types for the Redux DevTools Extension options to avoid an extra dependency, but the TS type for the options object wasn't exported publicly. We now export the `DevToolsEnhancerOptions` type.
The logic for generating a final URL has been updated to avoid adding an extra trailing `/`.
#### What's Changed
- Prevent `keepUnusedDataFor` values from overflowing `setTimeout` counter by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2595](https://togithub.com/reduxjs/redux-toolkit/pull/2595)
- remove typeof undefined checks where not necessary ππͺ by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1726](https://togithub.com/reduxjs/redux-toolkit/pull/1726)
- Update RDT options types, and export those + AnyListenerPredicate by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2596](https://togithub.com/reduxjs/redux-toolkit/pull/2596)
- Ensures there is no unexpected slash in url before query params by [@ygrishajev](https://togithub.com/ygrishajev) in [https://github.com/reduxjs/redux-toolkit/pull/2470](https://togithub.com/reduxjs/redux-toolkit/pull/2470)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.8.4...v1.8.5
### [`v1.8.4`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.4)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.3...v1.8.4)
This bugfix release adds exported TS types for RTKQ hooks for use in wrapping logic, adds `useDebugValue` to the hooks to improve display in the React DevTools, updates the inlined types for the Redux DevTools options, and fixes an issue in `createEntityAdapter` that could result in duplicate IDs being stored.
#### Changelog
##### RTKQ Hook Result Types
RTK's types heavily rely on inference to minimize the amount of type info users have to provide. However, this can also make it difficult to write functions that wrap calls to RTK APIs.
Some users have asked to have types that help them write "higher-order hooks". RTK now exports types that represent "the return object for a query/mutation hook with a given value": `TypedUseQueryHookResult` and `TypedUseMutationResult`. Both require `` as generics, like this:
```ts
const baseQuery = fetchBaseQuery({url: "https://some.server"});
type CustomHookResult = TypedUseQueryHookResult
const useMyCustomHook = (arg: MyArgObject) : CustomHookResult => {
return api.useGetSomeDataQuery(arg);
}
```
##### Redux DevTools Options Fixes
As of Redux DevTools 3.0, some of field names for custom DevTools options have changed to `actionsAllowlist` and `actionsDenylist`. Since we inline the types instead of having a separate dependency, we've updated our TS types to match that. No runtime behavior was changed.
##### Other Changes
RTKQ hooks now use `useDebugValue` to give a better preview of the current value in the React DevTools "Component" tab.
The `` component now does a better job of registering and cleaning up focus listeners.
Fixed a bug with `createEntityAdapter` that could allow duplicate IDs to be added depending on update parameters.
#### What's Changed
- fix: prevent duplicate ids when updating id of an element with the id of an existing element by [@samatar26](https://togithub.com/samatar26) in [https://github.com/reduxjs/redux-toolkit/pull/2020](https://togithub.com/reduxjs/redux-toolkit/pull/2020)
- ApiProvider: correctly register listeners, allow to disable listeners by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/2277](https://togithub.com/reduxjs/redux-toolkit/pull/2277)
- Update devtools options TS types based on RDT 3.0 by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2480](https://togithub.com/reduxjs/redux-toolkit/pull/2480)
- fix: typo in unhandled error message by [@MichielTondeur](https://togithub.com/MichielTondeur) in [https://github.com/reduxjs/redux-toolkit/pull/2538](https://togithub.com/reduxjs/redux-toolkit/pull/2538)
- Use useDebugValue in useQuery and useMutation hooks by [@kaankeskin](https://togithub.com/kaankeskin) in [https://github.com/reduxjs/redux-toolkit/pull/2500](https://togithub.com/reduxjs/redux-toolkit/pull/2500)
- add types for manually typing hook results in userland code by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2580](https://togithub.com/reduxjs/redux-toolkit/pull/2580)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.8.3...v1.8.4
### [`v1.8.3`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.3)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.2...v1.8.3)
This bugfix release fixes a few minor issues and bits of behavior, including updating the React-Redux peer dep to `^8.0.2` final, stable sorting in `createEntityAdapter.updateMany` and some initial state handling in `createSlice`.
#### Changelog
##### React-Redux Peer Dep
We'd previously published an RTK build that accepted React-Redux v8 beta as a peer dep (for use with RTK Query). Since React-Redux v8 is out now, we've updated the peer dep to `^8.0.2`.
##### Entity Adapter Updates
Previously, applying updates via `createEntityAdapter.updateMany` caused sorting order to change. Entities that had the same sorting result *should* have stayed in the same order relative to each other, but if one of those items had any updates, it would sort to the back of that group. This was due to items being removed from the lookup table and re-added, and since JS engines iterate keys in insertion order, the updated item would now end up compared later than before.
We've reworked the implementation of `updateMany` to avoid that. This also ended up fixing another issue where multiple update entries targeting the same item ID would only have the first applied.
#### `createSlice` Initial State
`createSlice` now logs an error if `initialState` is `undefined`. This is most commonly seen when users misspell `initialState`. It also has better handling for values that can't be frozen by Immer such as primitives.
##### RTK Query
Several assorted improvements, including TS types for `BaseQuery` and checking if the body can actually be safely stringified.
#### What's Changed
- Add Missing Else to enhanceEndpoints Function by [@kinson](https://togithub.com/kinson) in [https://github.com/reduxjs/redux-toolkit/pull/2386](https://togithub.com/reduxjs/redux-toolkit/pull/2386)
- Check initial state is draftable before using immer to freeze it. by [@EskiMojo14](https://togithub.com/EskiMojo14) in [https://github.com/reduxjs/redux-toolkit/pull/2378](https://togithub.com/reduxjs/redux-toolkit/pull/2378)
- Check that body isJsonifiable before stringify by [@ShaunDychko](https://togithub.com/ShaunDychko) in [https://github.com/reduxjs/redux-toolkit/pull/2330](https://togithub.com/reduxjs/redux-toolkit/pull/2330)
- Respect BaseQuery meta types when enhancing by [@TamasSzigeti](https://togithub.com/TamasSzigeti) in [https://github.com/reduxjs/redux-toolkit/pull/2225](https://togithub.com/reduxjs/redux-toolkit/pull/2225)
- Throw new error when initial state is undefined by [@dannielss](https://togithub.com/dannielss) in [https://github.com/reduxjs/redux-toolkit/pull/2461](https://togithub.com/reduxjs/redux-toolkit/pull/2461)
- Rewrite `updateMany` to ensure stable sorting order by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2464](https://togithub.com/reduxjs/redux-toolkit/pull/2464)
- Bump React-Redux peer dep by [@markerikson](https://togithub.com/markerikson) in https://github.com/reduxjs/redux-toolkit/commit/3033a33c3dd2ad743f02a44603bc77174599eebc
#### New Contributors
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.8.2...1.8.3
### [`v1.8.2`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.2)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.1...v1.8.2)
This bugfix release fixes a minor issue where calling `listenerMiddleware.startListening()` multiple times with the same `effect` callback reference would result in multiple entries being added. The correct behavior is that only the first entry is added, and later attempts to add the same effect callback reference just return the existing entry.
#### What's Changed
- Add type [@remarks](https://togithub.com/remarks) for configureStore's middleware by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/2252](https://togithub.com/reduxjs/redux-toolkit/pull/2252)
- Fix the "map values transpilation" bug, in yet another place by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2351](https://togithub.com/reduxjs/redux-toolkit/pull/2351)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.8.1...v1.8.2
### [`v1.8.1`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.1)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.0...v1.8.1)
This release updates RTK's peer dependencies to accept React 18 as a valid version. This should fix installation errors caused by NPM's "install all the peer deps and error if they don't match" behavior.
##### React-Redux and React 18
**Note**: If you are now using React 18, **we strongly recommend using [the React-Redux v8 beta instead of v7.x!](https://togithub.com/reduxjs/react-redux/releases/tag/v8.0.0-beta.3)**. 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.
### [`v1.8.0`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.0)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.7.2...v1.8.0)
This release adds the new "listener" middleware, updates `configureStore`'s types to better handle type inference from middleware that override `dispatch` return values, and updates our TS support matrix to drop support for TS < 4.1.
#### Changelog
##### New "Listener" Side Effects Middleware
RTK has integrated the thunk middleware since the beginning. However, thunks are imperative functions, and do not let you run code in response to dispatched actions. That use case has typically been covered with libraries like `redux-saga` (which handles side effects with "sagas" based on generator functions), `redux-observable` (which uses RxJS observables), or custom middleware.
We've added a new "listener" middleware to RTK to cover that use case. The listener middleware is created using `createListenerMiddleware()`, and lets you define "listener" entries that contain an "effect" callback with additional logic and a way to specify when that callback should run based on dispatched actions or state changes.
Conceptually, you can think of this as being similar to React's `useEffect` hook, except that it runs logic in response to Redux store updates instead of component props/state updates.
The listener middleware is intended to be a lightweight alternative to more widely used Redux async middleware like sagas and observables. While similar to thunks in level of complexity and concept, it can replicate some common saga usage patterns. We believe that the listener middleware can be used to replace most of the remaining use cases for sagas, but with a fraction of the bundle size and a much simpler API.
Listener effect callbacks have access to `dispatch` and `getState`, similar to thunks. The listener also receives a set of async workflow functions like `take`, `condition`, `pause`, `fork`, and `unsubscribe`, which allow writing more complex async logic.
Listeners can be defined statically by calling `listenerMiddleware.startListening()` during setup, or added and removed dynamically at runtime with special `dispatch(addListener())` and `dispatch(removeListener())` actions.
The API reference is available at:
https://redux-toolkit.js.org/api/createListenerMiddleware
Huge thanks to [@FaberVitale](https://togithub.com/FaberVitale) for major contributions in refining the middleware API and implementing key functionality.
Basic usage of the listener middleware looks like:
```js
import { configureStore, createListenerMiddleware } from '@reduxjs/toolkit'
import todosReducer, {
todoAdded,
todoToggled,
todoDeleted,
} from '../features/todos/todosSlice'
// Create the middleware instance and methods
const listenerMiddleware = createListenerMiddleware()
// Add one or more listener entries that look for specific actions.
// They may contain any sync or async logic, similar to thunks.
listenerMiddleware.startListening({
actionCreator: todoAdded,
effect: async (action, listenerApi) => {
// Run whatever additional side-effect-y logic you want here
console.log('Todo added: ', action.payload.text)
// Can cancel other running instances
listenerApi.cancelActiveListeners()
// Run async logic
const data = await fetchData()
// Pause until action dispatched or state changed
if (await listenerApi.condition(matchSomeAction)) {
// Use the listener API methods to dispatch, get state,
// unsubscribe the listener, start child tasks, and more
listenerApi.dispatch(todoAdded('Buy pet food'))
listenerApi.unsubscribe()
}
},
})
const store = configureStore({
reducer: {
todos: todosReducer,
},
// Add the listener middleware to the store.
// NOTE: Since this can receive actions with functions inside,
// it should go before the serializability check middleware
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().prepend(listenerMiddleware.middleware),
})
```
You can use it to write more complex async workflows, including pausing the effect callback until a condition check resolves, and forking "child tasks" to do additional work:
```js
// Track how many times each message was processed by the loop
const receivedMessages = {
a: 0,
b: 0,
c: 0,
}
const eventPollingStarted = createAction('serverPolling/started')
const eventPollingStopped = createAction('serverPolling/stopped')
listenerMiddleware.startListening({
actionCreator: eventPollingStarted,
effect: async (action, listenerApi) => {
// Only allow one instance of this listener to run at a time
listenerApi.unsubscribe()
// Start a child job that will infinitely loop receiving messages
const pollingTask = listenerApi.fork(async (forkApi) => {
try {
while (true) {
// Cancellation-aware pause for a new server message
const serverEvent = await forkApi.pause(pollForEvent())
// Process the message. In this case, just count the times we've seen this message.
if (serverEvent.type in receivedMessages) {
receivedMessages[
serverEvent.type as keyof typeof receivedMessages
]++
}
}
} catch (err) {
if (err instanceof TaskAbortError) {
// could do something here to track that the task was cancelled
}
}
})
// Wait for the "stop polling" action
await listenerApi.condition(eventPollingStopped.match)
pollingTask.cancel()
},
})
```
##### `configureStore` Middleware Type Improvements
Middleware can override the default return value of `dispatch`. `configureStore` tries to extract any declared `dispatch` type overrides from the `middleware` array, and uses that to alter the type of `store.dispatch`.
We identified some cases where the type inference wasn't working well enough, and rewrote the type behavior to be more correct.
##### TypeScript Support Matrix Updates
RTK now requires TS 4.1 or greater to work correctly, and we've dropped 4.0 and earlier from our support matrix.
##### Other Changes
The internal logic for the serializability middleware has been reorganized to allow skipping checks against actions, while still checking values in the state.
#### What's Changed
Since most of the implementation work on the middleware was done over the last few months, this list only contains the most recent PRs since 1.7.2. For details on the original use case discussions and the evolution of the middleware API over time, see:
- [RTK issue #237: Add an action listener middleware](https://togithub.com/reduxjs/redux-toolkit/issues/237)
- [RTK PR #547: yet another attempt at an action listener middleware](https://togithub.com/reduxjs/redux-toolkit/pull/547)
- [RTK discussion #1648: New experimental "action listener middleware" package available](https://togithub.com/reduxjs/redux-toolkit/discussions/1648)
PRs since 1.7.2:
- Rewrite MiddlewareArray and gDM for better Dispatch inference by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2001](https://togithub.com/reduxjs/redux-toolkit/pull/2001)
- Change listener middleware API name and signature by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2005](https://togithub.com/reduxjs/redux-toolkit/pull/2005)
- feat(alm): add cancellation message to TaskAbortError, listenerApi.signal & forkApi.signal. by [@FaberVitale](https://togithub.com/FaberVitale) in [https://github.com/reduxjs/redux-toolkit/pull/2023](https://togithub.com/reduxjs/redux-toolkit/pull/2023)
- \[fix]\[1.8.0-integration]\[alm]: missing type export by [@FaberVitale](https://togithub.com/FaberVitale) in [https://github.com/reduxjs/redux-toolkit/pull/2026](https://togithub.com/reduxjs/redux-toolkit/pull/2026)
- \[chore]\[1.8.0-integration]\[alm]: apply alm breaking API changes to counter-example by [@FaberVitale](https://togithub.com/FaberVitale) in [https://github.com/reduxjs/redux-toolkit/pull/2025](https://togithub.com/reduxjs/redux-toolkit/pull/2025)
- Reorganize serializable check conditions by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/2000](https://togithub.com/reduxjs/redux-toolkit/pull/2000)
- fix(alm): prevent zombie listeners caused by forked tasks by [@FaberVitale](https://togithub.com/FaberVitale) in [https://github.com/reduxjs/redux-toolkit/pull/2070](https://togithub.com/reduxjs/redux-toolkit/pull/2070)
- Integrate the listener middleware into the RTK package by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2072](https://togithub.com/reduxjs/redux-toolkit/pull/2072)
- fix(alm): cancel forkApi.delay and forkApi.pause if listener is cancelled or completed by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2074](https://togithub.com/reduxjs/redux-toolkit/pull/2074)
- chore(alm): update counter example to 1.8.0 by [@FaberVitale](https://togithub.com/FaberVitale) in [https://github.com/reduxjs/redux-toolkit/pull/2076](https://togithub.com/reduxjs/redux-toolkit/pull/2076)
- Enable cancelling active listeners when unsubscribing by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2078](https://togithub.com/reduxjs/redux-toolkit/pull/2078)
- v1.8.0 integration by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2024](https://togithub.com/reduxjs/redux-toolkit/pull/2024)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.7.2...v1.8.0
### [`v1.7.2`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.7.2)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.7.1...v1.7.2)
This release fixes a TS types bug with RTK Query generated selectors, makes the RTKQ structural sharing behavior configurable, adds an option to have the serializability middleware ignore all actions, and has several minor bugfixes and enhancements to RTK Query.
#### Changelog
##### RTK Query Selector TS Types Fix
Several users had reported that as of 1.7.0 selectors generated via `apiSlice.endpoint.select()` were failing to compile when used, with TS errors that looked like `Type '{}' is missing the following properties from type 'CombinedState<>`.
We've fixed the issue, and selectors should now compile correctly when used with TS.
##### Additional Configuration Options
RTK Query implements a technique called "structural sharing" to preserve existing object references if possible when data for an endpoint is re-fetched. RTKQ recurses over both data structures, and if the contents appear to be the same, keeps the existing values. That helps avoid potential unnecessary re-renders in the UI, because otherwise the *entire* re-fetched result would be new object references.
However, this update process can potentially take time depending on the size of the response. Endpoints can now be given a `structuralSharing` option that will turn that off to save on processing time:
```ts
const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: "https://example.com" }),
endpoints: (build) => ({
getEveryEntityInADatabase: build.query({
query: () => ({ url: "/i-cant-paginate-data" }),
structuralSharing: false,
}),
}),
});
```
Additionally, the serializability check middleware can now be customized with an `ignoreActions` option to exempt *all* actions from being checked. This is an escape hatch and isn't recommended for most apps:
```ts
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoreActions: true,
},
}),
});
```
##### Other API Improvements
If an `extraArgument` was provided to the thunk middleware during store configuration, that value is now passed along to the `prepareHeaders()` function:
```ts
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
thunk: {
extraArgument: { myCustomApiService },
},
}),
});
// ..later on
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: "https://example.com",
prepareHeaders: async (headers, { getState, extra }) => {
const token = getState().auth.token;
const somethingElse = await extra.myCustomApiService.someMethod();
// do things with somethingElse
return headers;
},
}),
});
```
The `invalidatesTags/providesTags` functions now receive the `action.meta` field as an argument, to help with potentially invalidating based on request/response headers.
##### Bug Fixes
`refetchOnFocus` now cleans up cache entries if a focus event is received and there are no active subscriptions, to avoid unnecessary requests.
Active polls are cleaned up when the last component for a given subscription unsubscribes.
The types for `builder.addMatcher` have been updated to support inference of guards without a `type` property.
#### What's Changed
- feat(meta): Passes meta to result description functions \[[#1904](https://togithub.com/reduxjs/redux-toolkit/issues/1904)] by [@bever1337](https://togithub.com/bever1337) in [https://github.com/reduxjs/redux-toolkit/pull/1910](https://togithub.com/reduxjs/redux-toolkit/pull/1910)
- Fix `addMatcher` typings by [@crcarrick](https://togithub.com/crcarrick) in [https://github.com/reduxjs/redux-toolkit/pull/1895](https://togithub.com/reduxjs/redux-toolkit/pull/1895)
- Pass baseQueryMeta into calculateProvidedBy by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1926](https://togithub.com/reduxjs/redux-toolkit/pull/1926)
- Cleanup polls on unsubscribeQueryResult by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1933](https://togithub.com/reduxjs/redux-toolkit/pull/1933)
- Add `extra` to `prepareHeaders`, update documentation + tests by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1922](https://togithub.com/reduxjs/redux-toolkit/pull/1922)
- fix `reducerPath` for query definitions by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1977](https://togithub.com/reduxjs/redux-toolkit/pull/1977)
- Update serialize documentation link by [@wuweiweiwu](https://togithub.com/wuweiweiwu) in [https://github.com/reduxjs/redux-toolkit/pull/1983](https://togithub.com/reduxjs/redux-toolkit/pull/1983)
- Refetch should not happen if no active subscribers by [@AlexanderArvidsson](https://togithub.com/AlexanderArvidsson) in [https://github.com/reduxjs/redux-toolkit/pull/1974](https://togithub.com/reduxjs/redux-toolkit/pull/1974)
- Add `ignoreActions` flag to serializable state middleware by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1984](https://togithub.com/reduxjs/redux-toolkit/pull/1984)
- RTKQ: configurable `structuralSharing` on endpoints/queries/createApi by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1954](https://togithub.com/reduxjs/redux-toolkit/pull/1954)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.7.1...v1.7.2
### [`v1.7.1`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.7.1)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.7.0...v1.7.1)
This release fixes a types issue with RTK 1.7.0 and TS 4.5, as seen in [#1829](https://togithub.com/reduxjs/redux-toolkit/issues/1829) .
#### What's Changed
- fix types for TS 4.5 by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1834](https://togithub.com/reduxjs/redux-toolkit/pull/1834)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.7.0...v1.7.1
### [`v1.7.0`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.7.0)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.6.2...v1.7.0)
This feature release has a wide variety of API improvements:
- updates RTK Query with support for SSR and rehydration
- allows sharing mutation results across components
- adds a new `currentData` field to query results
- adds several new options for customizing endpoints and base queries
- adds support for async `condition` options in `createAsyncThunk`
- updates `createSlice/createReducer` to accept a "lazy state initializer" function
- updates `createSlice` to avoid potential circular dependency issues by lazy-building its reducer
- updates Reselect and Redux-Thunk to the latest versions with much-improved TS support and new selector customization options
- Fixes a number of small code and types issues
```bash
npm i @reduxjs/toolkit@latest
yarn add @reduxjs/toolkit@latest
```
#### Changelog
##### RTK Query
##### RTK Query SSR and Rehydration Support
RTK Query now has support for SSR scenarios, such as the `getStaticProps/getServerSideProps` APIs in Next.js. Queries can be executed on the server using the existing `dispatch(someEndpoint.initiate())` thunks, and then collected using the new `await Promise.all(api.getRunningOperationPromises())` method.
API definitions can then provide an `extractRehydrationInfo` method that looks for a specific action type containing the fetched data, and return the data to initialize the API cache section of the store state.
The related `api.util.getRunningOperationPromise()` API adds a building block that may enable future support for React Suspense as well, and we'd encourage users to experiment with this idea.
##### Sharing Mutation Results Across Components
Mutation hooks provide status of in-progress requests, but as originally designed that information was unique per-component - there was no way for another component to see that request status data. But, we had several requests to enable this use case.
`useMutation` hooks now support a `fixedCacheKey` option that will store the result status in a common location, so multiple components can read the request status if needed.
This does mean that the data cannot easily be cleaned up automatically, so the mutation status object now includes a `reset()` function that can be used to clear that data.
##### Data Loading Updates
Query results now include a `currentData` field, which contains the latest data cached from the server for the *current* query arg. Additionally, `transformResponse` now receives the query arg as a parameter. These can be used to add additional derivation logic in cases when a hooks query arg has changed to represent a different value and the existing data no longer conceptually makes sense to keep displaying.
##### Data Serialization and Base Query Improvements
RTK Query originally only did shallow checks for query arg fields to determine if values had changed. This caused issues with infinite loops depending on user input.
The query hooks now use a "serialized stable value" hook internally to do more consistent comparisons of query args and eliminate those problems.
Also, `fetchBaseQuery` now supports a `paramsSerializer` option that allows customization of query string generation from the provided arguments, which enables better interaction with some backend APIs.
The `BaseQueryApi` and `prepareheaders` args now include fields for `endpoint` name, `type` to indicate if it's a query or mutation, and `forced` to indicate a re-fetch even if there was already a cache entry. These can be used to help determine headers like `Cache-Control: no-cache`.
##### Other RTK Query Improvements
API objects now have a `selectInvalidatedBy` function that accepts a root state object and an array of query tag objects, and returns a list of details on endpoints that would be invalidated. This can be used to help implement optimistic updates of paginated lists.
Fixed an issue serializing a query arg of `undefined`. Related, an empty JSON body now is stored as `null` instead of `undefined`.
There are now dev warnings for potential mistakes in endpoint setup, like a query function that does not return a `data` field.
Lazy query trigger promises can now be unwrapped similar to mutations.
Fixed a type error that led the endpoint return type to be erroneously used as a state key, which caused generated selectors to have an inferred `state: never` argument.
Fixed `transformResponse` to correctly receive the `originalArgs` as its third parameter.
`api.util.resetApiState` will now clear out cached values in `useQuery` hooks.
The `RetryOptions` interface is now exported, which resolves a TS build error when using the hooks with TS declarations.
##### RTK Core
##### `createSlice` Lazy Reducers and Circular Dependencies
For the last couple years we've specifically recommended [using a "feature folder" structure with a single "slice" file of logic per feature](https://redux.js.org/style-guide/style-guide#structure-files-as-feature-folders-with-single-file-logic), and `createSlice` makes that pattern really easy - no need to have separate folders and files for `/actions` and `/constants` any more.
The one downside to the "slice file" pattern is in cases when slice A needs to import actions from slice B to respond to them, and slice B also needs to listen to slice A. This circular import then causes runtime errors, because one of the modules will not have finished initializing by the time the other executes the module body. That causes the exports to be undefined, and `createSlice` throws an error because you can't pass `undefined` to `builder.addCase()` in `extraReducers`. (Or, worse, there's no obvious error and things break later.)
There are [well-known patterns for breaking circular dependencies](https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javascript-typescript-a04c987cf0de), typically requiring extracting shared logic into a separate file. For RTK, this usually means [calling `createAction` separately, and importing those action creators into both slices](https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices).
While this is a rarer problem, it's one that *can* happen in real usage, and it's also been a semi-frequently listed concern from users who didn't want to use RTK.
We've updated `createSlice` to now lazily create its reducer function *the first time you try to call it*. That delay in instantiation should **eliminate circular dependencies as a runtime error in `createSlice`**.
##### `createAsyncThunk` Improvements
The `condition` option may now be `async`, which enables scenarios like checking if an existing operation is running and resolving the promise when the other instance is done.
If an `idGenerator` function is provided, it will now be given the `thunkArg` value as a parameter, which enables generating custom IDs based on the request data.
The `createAsyncThunk` types were updated to correctly handle type inference when using `rejectWithValue()`.
##### Other RTK Improvements
`createSlice` and `createReducer` now accept a "lazy state initializer" function as the `initialState` argument. If provided, the initializer will be called to produce a new initial state value any time the reducer is given `undefined` as its state argument. This can be useful for cases like reading from `localStorage`, as well as testing.
The `isPlainObject` util has been updated to match the implementation in other Redux libs.
The UMD builds of RTK Query now attach as `window.RTKQ` instead of overwriting `window.RTK`.
Fixed an issue with sourcemap loading due to an incorrect filename replacement.
##### Dependency Updates
We've updated our deps to the latest versions:
- [**Reselect 4.1.x**](https://togithub.com/reduxjs/reselect/releases/tag/v4.1.0): Reselect has brand-new customization capabilities for selectors, including configuring cache sizes > 1 and the ability to run equality checks on selector results. It also now has completely rewritten TS types that do a much better job of inferring arguments and catch previously broken patterns.
- [**Redux Thunk 2.4.0**](https://togithub.com/reduxjs/redux-thunk/releases/tag/v2.4.0): The thunk middleware also has improved types, as well as an optional "global override" import to modify the type of `Dispatch` everywhere in the app
We've also lowered RTK's peer dependency on React from `^16.14` to `^16.9`, as we just need hooks to be available.
##### Other Redux Development Work
The Redux team has also been working on several other updates to the Redux family of libraries.
##### React-Redux v8.0 Beta
We've rewritten React-Redux to add compatibility with the upcoming React 18 release and converted its codebase to TypeScript. It still supports React 16.8+/17 via a `/compat` entry point. We'd appreciate further testing from the community so we can confirm it works as expected in real apps before final release. For details on the changes, see:
- https://github.com/reduxjs/react-redux/releases/tag/v8.0.0-beta.0
##### RTK "Action Listener Middleware" Alpha
We have been working on [a new "action listener middleware"](https://togithub.com/reduxjs/redux-toolkit/discussions/1648) that we hope to release in an upcoming version of RTK. It's designed to let users write code that runs in response to dispatched actions and state changes, including simple callbacks and moderately complex async workflows. The current design appears capable of handling many of the use cases that previously required use of the Redux-Saga or Redux-Observable middlewares, but with a smaller bundle size and simpler API.
The listener middleware is still in alpha, but we'd really appreciate more users testing it out and giving us additional feedback to help us finalize the API and make sure it covers the right use cases.
##### RTK Query CodeGen
The [RTK Query OpenAPI codegen tool](https://redux-toolkit.js.org/rtk-query/usage/code-generation) has been rewritten with new options and improved output.
#### What's Changed
- fix "isLoading briefly flips back to `true`" [#1519](https://togithub.com/reduxjs/redux-toolkit/issues/1519) by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1520](https://togithub.com/reduxjs/redux-toolkit/pull/1520)
- feat(createAsyncThunk): async condition by [@thorn0](https://togithub.com/thorn0) in [https://github.com/reduxjs/redux-toolkit/pull/1496](https://togithub.com/reduxjs/redux-toolkit/pull/1496)
- add `arg` to `transformResponse` by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1521](https://togithub.com/reduxjs/redux-toolkit/pull/1521)
- add `currentData` property to hook results. by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1500](https://togithub.com/reduxjs/redux-toolkit/pull/1500)
- use `useSerializedStableValue` for value comparison by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1533](https://togithub.com/reduxjs/redux-toolkit/pull/1533)
- fix(useLazyQuery): added docs for preferCache option by [@akashshyamdev](https://togithub.com/akashshyamdev) in [https://github.com/reduxjs/redux-toolkit/pull/1541](https://togithub.com/reduxjs/redux-toolkit/pull/1541)
- correctly handle console logs in tests by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1567](https://togithub.com/reduxjs/redux-toolkit/pull/1567)
- add `reset` method to useMutation hook by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1476](https://togithub.com/reduxjs/redux-toolkit/pull/1476)
- allow for "shared component results" using the `useMutation` hook by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1477](https://togithub.com/reduxjs/redux-toolkit/pull/1477)
- π Fix bug with `useMutation` shared results by [@Shrugsy](https://togithub.com/Shrugsy) in [https://github.com/reduxjs/redux-toolkit/pull/1616](https://togithub.com/reduxjs/redux-toolkit/pull/1616)
- pass the ThunkArg to the idGenerator function by [@loursbourg](https://togithub.com/loursbourg) in [https://github.com/reduxjs/redux-toolkit/pull/1600](https://togithub.com/reduxjs/redux-toolkit/pull/1600)
- Support a custom paramsSerializer on fetchBaseQuery by [@msutkowski](https://togithub.com/msutkowski) in [https://github.com/reduxjs/redux-toolkit/pull/1594](https://togithub.com/reduxjs/redux-toolkit/pull/1594)
- SSR & rehydration support, suspense foundations by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1277](https://togithub.com/reduxjs/redux-toolkit/pull/1277)
- add `endpoint`, `type` and `forced` to `BaseQueryApi` and `prepareHeaders` by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1656](https://togithub.com/reduxjs/redux-toolkit/pull/1656)
- split off signature without `AsyncThunkConfig` for better inference by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1644](https://togithub.com/reduxjs/redux-toolkit/pull/1644)
- Update createReducer to accept a lazy state init function by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/1662](https://togithub.com/reduxjs/redux-toolkit/pull/1662)
- add `selectInvalidatedBy` by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1665](https://togithub.com/reduxjs/redux-toolkit/pull/1665)
- Update Yarn from 2.4 to 3.1 by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/1688](https://togithub.com/reduxjs/redux-toolkit/pull/1688)
- allow for circular references by building reducer lazily on first reducer call by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1686](https://togithub.com/reduxjs/redux-toolkit/pull/1686)
- Update deps for 1.7 by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/1692](https://togithub.com/reduxjs/redux-toolkit/pull/1692)
- fetchBaseQuery: return nullon empty body for JSON. Add DevWarnings by [@phryneas](https://togithub.com/phryneas) in [#1699](https://togithub.com/reduxjs/redux-toolkit/issues/1699)
- Add unwrap to QueryActionCreatorResult and update LazyQueryTrigger by [@msutkowski](https://togithub.com/msutkowski) in [#1701](https://togithub.com/reduxjs/redux-toolkit/issues/1701)
- Only set originalArgs if they're not undefined by [@phryneas](https://togithub.com/phryneas) in [#1711](https://togithub.com/reduxjs/redux-toolkit/issues/1711)
- Treat null as a valid plain object prototype in isPlainObject() in order to sync the util across reduxjs/\* repositories by [@Ilyklem](https://togithub.com/Ilyklem) in [#1734](https://togithub.com/reduxjs/redux-toolkit/issues/1734)
- export RetryOptions interface from retry.ts by [@colemars](https://togithub.com/colemars) in [#1751](https://togithub.com/reduxjs/redux-toolkit/issues/1751)
- fix: api.util.resetApiState should reset useQuery hooks by [@phryneas](https://togithub.com/phryneas) in [#1735](https://togithub.com/reduxjs/redux-toolkit/issues/1735)
- fix issue where the global RTK object got overwritten in the UMD files by [@Antignote](https://togithub.com/Antignote) in [https://github.com/reduxjs/redux-toolkit/pull/1763](https://togithub.com/reduxjs/redux-toolkit/pull/1763)
- Update dependencies and selector types by [@markerikson](https://togithub.com/markerikson) in [#1772](https://togithub.com/reduxjs/redux-toolkit/issues/1772)
- Fix broken sourcemap output due to bad filename replacement by [@markerikson](https://togithub.com/markerikson) in [#1773](https://togithub.com/reduxjs/redux-toolkit/issues/1773)
- Override unwrap behavior for buildInitiateQuery, update tests by [@msutkowski](https://togithub.com/msutkowski) in [#1786](https://togithub.com/reduxjs/redux-toolkit/issues/1786)
- Fix incorrect RTKQ endpoint definition types for correct selector typings by [@markerikson](https://togithub.com/markerikson) in [#1818](https://togithub.com/reduxjs/redux-toolkit/issues/1818)
- Use originalArgs in transformResponse by [@msutkowski](https://togithub.com/msutkowski) in [#1819](https://togithub.com/reduxjs/redux-toolkit/issues/1819)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.6.2...v1.7.0
### [`v1.6.2`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.6.2)
[Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.6.1...v1.6.2)
This release fixes several small issues with RTK Query, as well as a regression in the `createAsyncThunk` types and an issue with sourcemap URLs.
#### Changelog
##### RTK Query Fixes
The `isLoading` flag should only ever be `true` on the first run of a hook, but would sometimes briefly flip to `true` on later calls. That should now stay the correct value.
`fetchBaseQuery` should now work properly when used in conjunction with `node-fetch`.
The `BaseQueryApi` object now correctly includes the `extra` argument that was provided when configuring the thunk middleware, if any.
##### Other Fixes
Sourcemap URLs should now be correct, especially for the CommonJS build artifacts.
`createAsyncThunk`'s types have been updated to correctly infer return values when working with enums.
Lots of assorted docs tweaks and updates!
#### What's Changed
- Add extra to BaseQueryApi by [@ricksanchez](https://togithub.com/ricksanchez) in [https://github.com/reduxjs/redux-toolkit/pull/1378](https://togithub.com/reduxjs/redux-toolkit/pull/1378)
- fix: point sourceMappingURL to correct sourcemaps in build artifacts by [@jawadsh123](https://togithub.com/jawadsh123) in [https://github.com/reduxjs/redux-toolkit/pull/1459](https://togithub.com/reduxjs/redux-toolkit/pull/1459)
- fix: `createAsyncThunk` union return values fall back to allowing only single member by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1449](https://togithub.com/reduxjs/redux-toolkit/pull/1449)
- fix `fetchBaseQuery` for usage with `node-fetch` by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1473](https://togithub.com/reduxjs/redux-toolkit/pull/1473)
- fix "isLoading briefly flips back to `true`" [#1519](https://togithub.com/reduxjs/redux-toolkit/issues/1519) by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1520](https://togithub.com/reduxjs/redux-toolkit/pull/1520)
**Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.6.1...v1.6.2
Configuration
π Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
π¦ Automerge: Disabled by config. Please merge this manually once you are satisfied.
β» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
π Ignore: Close this PR and you won't be reminded about this update again.
[ ] If you want to rebase/retry this PR, click this checkbox.
This PR has been generated by Mend Renovate. View repository job log here.
This PR contains the following updates:
^1.6.1
->1.8.5
Release Notes
reduxjs/redux-toolkit
### [`v1.8.5`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.5) [Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.4...v1.8.5) This bugfix releas fixes an issue with large `keepUnusedDataFor` values overflowing JS timers, exports the types for the Redux DevTools Extension option, and and improves behavior of URL string generation. #### Changelog ##### `keepUnusedDataFor` Timer Fix `keepUnusedDataFor` accepts a value in seconds. When there are no more active subscriptions for a piece of data, RTKQ will set a timer using `setTimeout`, and `keepUnusedDataFor * 1000` as the timer value. We've been advising users that if they want to keep data in the cache forever that they should use a very large value for `keepUnusedDataFor`, such as 10 years in seconds. However, it turns out that JS engines use a 32-bit signed int for timers, and 32-bits in milliseconds is only 24.8 days. If a timer is given a value larger than that, it triggers immediately. We've updated the internal logic to clamp the `keepUnusedDataFor` value to be between 0 and `THIRTY_TWO_BIT_MAX_TIMER_SECONDS - 1`. Note that in RTK 1.9 (coming soon), RTKQ will also accept `Infinity` as a special `keepUnusedDataFor` value to indicate cached data should never be expired. ##### Other Changes RTK inlines the TS types for the Redux DevTools Extension options to avoid an extra dependency, but the TS type for the options object wasn't exported publicly. We now export the `DevToolsEnhancerOptions` type. The logic for generating a final URL has been updated to avoid adding an extra trailing `/`. #### What's Changed - Prevent `keepUnusedDataFor` values from overflowing `setTimeout` counter by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2595](https://togithub.com/reduxjs/redux-toolkit/pull/2595) - remove typeof undefined checks where not necessary ππͺ by [@phryneas](https://togithub.com/phryneas) in [https://github.com/reduxjs/redux-toolkit/pull/1726](https://togithub.com/reduxjs/redux-toolkit/pull/1726) - Update RDT options types, and export those + AnyListenerPredicate by [@markerikson](https://togithub.com/markerikson) in [https://github.com/reduxjs/redux-toolkit/pull/2596](https://togithub.com/reduxjs/redux-toolkit/pull/2596) - Ensures there is no unexpected slash in url before query params by [@ygrishajev](https://togithub.com/ygrishajev) in [https://github.com/reduxjs/redux-toolkit/pull/2470](https://togithub.com/reduxjs/redux-toolkit/pull/2470) **Full Changelog**: https://github.com/reduxjs/redux-toolkit/compare/v1.8.4...v1.8.5 ### [`v1.8.4`](https://togithub.com/reduxjs/redux-toolkit/releases/tag/v1.8.4) [Compare Source](https://togithub.com/reduxjs/redux-toolkit/compare/v1.8.3...v1.8.4) This bugfix release adds exported TS types for RTKQ hooks for use in wrapping logic, adds `useDebugValue` to the hooks to improve display in the React DevTools, updates the inlined types for the Redux DevTools options, and fixes an issue in `createEntityAdapter` that could result in duplicate IDs being stored. #### Changelog ##### RTKQ Hook Result Types RTK's types heavily rely on inference to minimize the amount of type info users have to provide. However, this can also make it difficult to write functions that wrap calls to RTK APIs. Some users have asked to have types that help them write "higher-order hooks". RTK now exports types that represent "the return object for a query/mutation hook with a given value": `TypedUseQueryHookResult` and `TypedUseMutationResult`. Both require `Configuration
π Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
π¦ Automerge: Disabled by config. Please merge this manually once you are satisfied.
β» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
π Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate. View repository job log here.