Skip to content

Commit 1feb9ba

Browse files
committed
Merge branch 'master' into v2.0-integration
# Conflicts: # packages/toolkit/package.json # packages/toolkit/src/configureStore.ts # packages/toolkit/src/createAction.ts # packages/toolkit/src/listenerMiddleware/index.ts # packages/toolkit/src/query/tests/createApi.test.ts # packages/toolkit/src/tsHelpers.ts # packages/toolkit/src/utils.ts # website/package.json # yarn.lock
2 parents 34db089 + d3bb412 commit 1feb9ba

37 files changed

+559
-137
lines changed

docs/api/configureStore.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ to the store setup for a better development experience.
1818

1919
```ts no-transpile
2020
type ConfigureEnhancersCallback = (
21-
defaultEnhancers: StoreEnhancer[]
21+
defaultEnhancers: EnhancerArray<[StoreEnhancer]>
2222
) => StoreEnhancer[]
2323

2424
interface ConfigureStoreOptions<
@@ -107,7 +107,8 @@ a list of the specific options that are available.
107107
Defaults to `true`.
108108

109109
#### `trace`
110-
The Redux DevTools Extension recently added [support for showing action stack traces](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Features/Trace.md) that show exactly where each action was dispatched.
110+
111+
The Redux DevTools Extension recently added [support for showing action stack traces](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Features/Trace.md) that show exactly where each action was dispatched.
111112
Capturing the traces can add a bit of overhead, so the DevTools Extension allows users to configure whether action stack traces are captured by [setting the 'trace' argument](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md#trace).
112113
If the DevTools are enabled by passing `true` or an object, then `configureStore` will default to enabling capturing action stack traces in development mode only.
113114

@@ -129,7 +130,7 @@ If defined as a callback function, it will be called with the existing array of
129130
and should return a new array of enhancers. This is primarily useful for cases where a store enhancer needs to be added
130131
in front of `applyMiddleware`, such as `redux-first-router` or `redux-offline`.
131132

132-
Example: `enhancers: (defaultEnhancers) => [offline, ...defaultEnhancers]` will result in a final setup
133+
Example: `enhancers: (defaultEnhancers) => defaultEnhancers.prepend(offline)` will result in a final setup
133134
of `[offline, applyMiddleware, devToolsExtension]`.
134135

135136
## Usage
@@ -195,7 +196,7 @@ const preloadedState = {
195196
visibilityFilter: 'SHOW_COMPLETED',
196197
}
197198
198-
const debounceNotify = _.debounce(notify => notify());
199+
const debounceNotify = _.debounce((notify) => notify())
199200
200201
const store = configureStore({
201202
reducer,

docs/api/createListenerMiddleware.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ These methods provide the ability to write conditional logic based on future dis
422422

423423
Both these methods are cancellation-aware, and will throw a `TaskAbortError` if the listener instance is cancelled while paused.
424424

425+
Note that both `take` and `condition` will only resolve **after the next action** has been dispatched. They do not resolve immediately even if their predicate would return true for the current state.
426+
425427
### Child Tasks
426428

427429
- `fork: (executor: (forkApi: ForkApi) => T | Promise<T>) => ForkedTask<T>`: Launches a "child task" that may be used to accomplish additional work. Accepts any sync or async function as its argument, and returns a `{result, cancel}` object that can be used to check the final status and return value of the child task, or cancel it while in-progress.
@@ -831,7 +833,7 @@ First, you can import effect callbacks from slice files into the middleware file
831833
832834
```ts no-transpile title="app/listenerMiddleware.ts"
833835
import { action1, listener1 } from '../features/feature1/feature1Slice'
834-
import { action2, listener2 } from '../features/feature2/feature1Slice'
836+
import { action2, listener2 } from '../features/feature2/feature2Slice'
835837

836838
listenerMiddleware.startListening({ actionCreator: action1, effect: listener1 })
837839
listenerMiddleware.startListening({ actionCreator: action2, effect: listener2 })

docs/rtk-query/api/created-api/endpoints.mdx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ When dispatching an action creator, you're responsible for storing a reference t
9292

9393
#### Example
9494

95-
```tsx title="initiate query example"
95+
```tsx no-transpile title="initiate query example"
9696
import { useState } from 'react'
9797
import { useAppDispatch } from './store/hooks'
9898
import { api } from './services/api'
@@ -119,7 +119,7 @@ function App() {
119119
}
120120
```
121121

122-
```tsx title="initiate mutation example"
122+
```tsx no-transpile title="initiate mutation example"
123123
import { useState } from 'react'
124124
import { useAppDispatch } from './store/hooks'
125125
import { api, Post } from './services/api'
@@ -187,7 +187,7 @@ Each call to `.select(someCacheKey)` returns a _new_ selector function instance.
187187
188188
#### Example
189189
190-
```tsx title="select query example"
190+
```tsx no-transpile title="select query example"
191191
import { useState, useMemo } from 'react'
192192
import { useAppDispatch, useAppSelector } from './store/hooks'
193193
import { api } from './services/api'
@@ -198,9 +198,10 @@ function App() {
198198
// highlight-start
199199
// useMemo is used to only call `.select()` when required.
200200
// Each call will create a new selector function instance
201-
const selectPost = useMemo(() => api.endpoints.getPost.select(postId), [
202-
postId,
203-
])
201+
const selectPost = useMemo(
202+
() => api.endpoints.getPost.select(postId),
203+
[postId]
204+
)
204205
const { data, isLoading } = useAppSelector(selectPost)
205206
// highlight-end
206207

@@ -223,7 +224,7 @@ function App() {
223224
}
224225
```
225226

226-
```tsx title="select mutation example"
227+
```tsx no-transpile title="select mutation example"
227228
import { useState, useMemo } from 'react'
228229
import { skipToken } from '@reduxjs/toolkit/query'
229230
import { useAppDispatch, useAppSelector } from './store/hooks'

docs/rtk-query/usage-with-typescript.mdx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ export const api = createApi({
467467
export const { useGetPostQuery } = api
468468
```
469469
470-
```tsx title="Using skip in a component"
470+
```tsx no-transpile title="Using skip in a component"
471471
import { useGetPostQuery } from './api'
472472
473473
function MaybePost({ id }: { id?: number }) {
@@ -486,7 +486,7 @@ While you might be able to convince yourself that the query won't be called unle
486486

487487
RTK Query provides a `skipToken` export which can be used as an alternative to the `skip` option in order to skip queries, while remaining type-safe. When `skipToken` is passed as the query argument to `useQuery`, `useQueryState` or `useQuerySubscription`, it provides the same effect as setting `skip: true` in the query options, while also being a valid argument in scenarios where the `arg` might be undefined otherwise.
488488

489-
```tsx title="Using skipToken in a component"
489+
```tsx no-transpile title="Using skipToken in a component"
490490
import { skipToken } from '@reduxjs/toolkit/query/react'
491491
import { useGetPostQuery } from './api'
492492

@@ -566,7 +566,7 @@ export interface SerializedError {
566566
When using `fetchBaseQuery`, the `error` property returned from a hook will have the type `FetchBaseQueryError | SerializedError | undefined`.
567567
If an error is present, you can access error properties after narrowing the type to either `FetchBaseQueryError` or `SerializedError`.
568568

569-
```tsx
569+
```tsx no-transpile
570570
import { api } from './services/api'
571571

572572
function PostDetail() {
@@ -587,10 +587,9 @@ function PostDetail() {
587587
<div>{errMsg}</div>
588588
</div>
589589
)
590-
}
591-
else {
592-
// you can access all properties of `SerializedError` here
593-
return <div>{error.message}</div>
590+
} else {
591+
// you can access all properties of `SerializedError` here
592+
return <div>{error.message}</div>
594593
}
595594
}
596595

@@ -617,7 +616,7 @@ In order to safely access properties of the error, you must first narrow the typ
617616
This can be done using a [type predicate](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates)
618617
as shown below.
619618

620-
```tsx title="services/helpers.ts"
619+
```tsx no-transpile title="services/helpers.ts"
621620
import { FetchBaseQueryError } from '@reduxjs/toolkit/query'
622621

623622
/**
@@ -644,7 +643,7 @@ export function isErrorWithMessage(
644643
}
645644
```
646645

647-
```tsx title="addPost.tsx"
646+
```tsx no-transpile title="addPost.tsx"
648647
import { useState } from 'react'
649648
import { useSnackbar } from 'notistack'
650649
import { api } from './services/api'

docs/rtk-query/usage/automated-refetching.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ const api = createApi({
232232
Note that for the example above, the `id` is used where possible on a successful result. In the case of an error, no result is supplied, and we still consider that it has provided the general `'Post'` tag type rather than any specific instance of that tag.
233233

234234
:::tip Advanced List Invalidation
235-
In order to provide stronger control over invalidating the appropriate data, you can use an arbitrary ID such a `'LIST'` for a given tag. See [Advanced Invalidation with abstract tag IDs](#advanced-invalidation-with-abstract-tag-ids) for additional details.
235+
In order to provide stronger control over invalidating the appropriate data, you can use an arbitrary ID such as `'LIST'` for a given tag. See [Advanced Invalidation with abstract tag IDs](#advanced-invalidation-with-abstract-tag-ids) for additional details.
236236
:::
237237

238238
### Invalidating cache data
@@ -381,7 +381,7 @@ const api = createApi({
381381
For the example above, rather than invalidating any tag with the type `'Post'`, calling the `editPost` mutation function will now only invalidate a tag for the provided `id`. I.e. if cached data from an endpoint does not provide a `'Post'` for that same `id`, it will remain considered as 'valid', and will not be triggered to automatically re-fetch.
382382
383383
:::tip Using abstract tag IDs
384-
In order to provide stronger control over invalidating the appropriate data, you can use an arbitrary ID such a `'LIST'` for a given tag. See [Advanced Invalidation with abstract tag IDs](#advanced-invalidation-with-abstract-tag-ids) for additional details.
384+
In order to provide stronger control over invalidating the appropriate data, you can use an arbitrary ID such as `'LIST'` for a given tag. See [Advanced Invalidation with abstract tag IDs](#advanced-invalidation-with-abstract-tag-ids) for additional details.
385385
:::
386386
387387
## Tag Invalidation Behavior
@@ -668,7 +668,7 @@ export const api = createApi({
668668
export const { useGetPostsQuery, useGetPostQuery, useAddPostMutation } = api
669669
```
670670

671-
```tsx title="App.tsx"
671+
```tsx no-transpile title="App.tsx"
672672
function App() {
673673
const { data: posts } = useGetPostsQuery()
674674
const [addPost] = useAddPostMutation()
@@ -742,7 +742,7 @@ export const api = createApi({
742742
export const { useGetPostsQuery, useAddPostMutation, useGetPostQuery } = api
743743
```
744744

745-
```tsx title="App.tsx"
745+
```tsx no-transpile title="App.tsx"
746746
function App() {
747747
const { data: posts } = useGetPostsQuery()
748748
const [addPost] = useAddPostMutation()

docs/rtk-query/usage/cache-behavior.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ Calling the `refetch` function will force refetch the associated query.
120120

121121
Alternatively, you can dispatch the `initiate` thunk action for an endpoint, passing the option `forceRefetch: true` to the thunk action creator for the same effect.
122122

123-
```tsx title="Force refetch example"
123+
```tsx no-transpile title="Force refetch example"
124124
import { useDispatch } from 'react-redux'
125125
import { useGetPostsQuery } from './api'
126126

@@ -197,7 +197,7 @@ export const api = createApi({
197197
})
198198
```
199199

200-
```tsx title="Forcing refetch on component mount"
200+
```tsx no-transpile title="Forcing refetch on component mount"
201201
import { useGetPostsQuery } from './api'
202202

203203
const Component = () => {

docs/rtk-query/usage/error-handling.mdx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ If your query or mutation happens to throw an error when using [fetchBaseQuery](
1616

1717
### Error Display Examples
1818

19-
```tsx title="Query Error"
19+
```tsx no-transpile title="Query Error"
2020
function PostsList() {
2121
const { data, error } = useGetPostsQuery()
2222

@@ -28,7 +28,7 @@ function PostsList() {
2828
}
2929
```
3030

31-
```tsx title="Mutation Error"
31+
```tsx no-transpile title="Mutation Error"
3232
function AddPost() {
3333
const [addPost, { error }] = useAddPostMutation()
3434

@@ -52,7 +52,7 @@ addPost({ id: 1, name: 'Example' })
5252

5353
:::
5454

55-
```tsx title="Manually selecting an error"
55+
```tsx no-transpile title="Manually selecting an error"
5656
function PostsList() {
5757
const { error } = useSelector(api.endpoints.getPosts.select())
5858

@@ -88,15 +88,14 @@ import { toast } from 'your-cool-library'
8888
/**
8989
* Log a warning and show a toast!
9090
*/
91-
export const rtkQueryErrorLogger: Middleware = (api: MiddlewareAPI) => (
92-
next
93-
) => (action) => {
94-
// RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
95-
if (isRejectedWithValue(action)) {
96-
console.warn('We got a rejected action!')
97-
toast.warn({ title: 'Async error!', message: action.error.data.message })
91+
export const rtkQueryErrorLogger: Middleware =
92+
(api: MiddlewareAPI) => (next) => (action) => {
93+
// RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
94+
if (isRejectedWithValue(action)) {
95+
console.warn('We got a rejected action!')
96+
toast.warn({ title: 'Async error!', message: action.error.data.message })
97+
}
98+
99+
return next(action)
98100
}
99-
100-
return next(action)
101-
}
102101
```

docs/rtk-query/usage/manual-cache-updates.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ callback for a mutation without a good reason, as RTK Query is intended to be us
217217
your cached data as a reflection of the server-side state.
218218
:::
219219

220-
```tsx title="General manual cache update example"
220+
```tsx no-transpile title="General manual cache update example"
221221
import { api } from './api'
222222
import { useAppDispatch } from './store/hooks'
223223

docs/rtk-query/usage/migrating-to-rtk-query.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export type RootState = ReturnType<typeof store.getState>
169169
170170
In order to have the store accessible within our app, we will wrap our `App` component with a [`Provider`](https://react-redux.js.org/api/provider) component from `react-redux`.
171171
172-
```tsx title="src/index.ts"
172+
```tsx no-transpile title="src/index.ts"
173173
import { render } from 'react-dom'
174174
// highlight-start
175175
import { Provider } from 'react-redux'
@@ -223,9 +223,9 @@ export type RootState = {
223223
pokemon: typeof initialPokemonSlice
224224
}
225225

226-
export declare const store: EnhancedStore<RootState>
226+
export declare const store: EnhancedStore<RootState>
227227
export type AppDispatch = typeof store.dispatch
228-
export declare const useAppDispatch: () => (...args: any[])=> any;
228+
export declare const useAppDispatch: () => (...args: any[]) => any
229229

230230
// file: src/hooks.ts
231231
import { useEffect } from 'react'
@@ -276,7 +276,7 @@ Our implementation below provides the following behaviour in the component:
276276
- When our component is mounted, if a request for the provided pokemon name has not already been sent for the session, send the request off
277277
- The hook always provides the latest received `data` when available, as well as the request status booleans `isUninitialized`, `isPending`, `isFulfilled` & `isRejected` in order to determine the current UI at any given moment as a function of our state.
278278

279-
```tsx title="src/App.tsx"
279+
```tsx no-transpile title="src/App.tsx"
280280
import * as React from 'react'
281281
// highlight-start
282282
import { useGetPokemonByNameQuery } from './hooks'

docs/rtk-query/usage/mutations.mdx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ const api = createApi({
5252
// Pick out data and prevent nested properties in a hook or selector
5353
transformResponse: (response: { data: Post }, meta, arg) => response.data,
5454
// Pick out errors and prevent nested properties in a hook or selector
55-
transformErrorResponse: (response: { status: string | number }, meta, arg) => response.status,
55+
transformErrorResponse: (
56+
response: { status: string | number },
57+
meta,
58+
arg
59+
) => response.status,
5660
invalidatesTags: ['Post'],
5761
// onQueryStarted is useful for optimistic updates
5862
// The 2nd parameter is the destructured `MutationLifecycleApi`
@@ -177,7 +181,7 @@ When using `fixedCacheKey`, the `originalArgs` property is not able to be shared
177181

178182
This is a modified version of the complete example you can see at the bottom of the page to highlight the `updatePost` mutation. In this scenario, a post is fetched with `useQuery`, and then an `EditablePostName` component is rendered that allows us to edit the name of the post.
179183

180-
```tsx title="src/features/posts/PostDetail.tsx"
184+
```tsx no-transpile title="src/features/posts/PostDetail.tsx"
181185
export const PostDetail = () => {
182186
const { id } = useParams<{ id: any }>()
183187

0 commit comments

Comments
 (0)