Skip to content

Commit c11887e

Browse files
committed
Merge remote-tracking branch 'origin/master' into yarn-workspaces
2 parents 70dbf21 + 18368af commit c11887e

File tree

70 files changed

+932
-354
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+932
-354
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [phryneas]

.github/workflows/tests.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ jobs:
8989
fail-fast: false
9090
matrix:
9191
node: ['14.x']
92-
ts: ['3.9', '4.0', '4.1', '4.2', 'next']
92+
ts: ['3.9', '4.0', '4.1', '4.2', '4.3', 'next']
9393
steps:
9494
- name: Checkout repo
9595
uses: actions/checkout@v2
@@ -125,6 +125,10 @@ jobs:
125125
if: ${{ matrix.ts < 4.1 }}
126126
run: sed -i -e 's/@pre41-ts-ignore/@ts-ignore/' -e '/pre41-remove-start/,/pre41-remove-end/d' ./src/tests/*.* ./src/query/tests/*.ts*
127127

128+
- name: 'disable strictOptionalProperties'
129+
if: ${{ matrix.ts == 'next' }}
130+
run: sed -i -e 's|//\(.*strictOptionalProperties.*\)$|\1|' tsconfig.base.json
131+
128132
- name: Test types
129133
run: |
130134
yarn tsc --version

docs/api/createEntityAdapter.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ The primary content of an entity adapter is a set of generated reducer functions
208208
- `setAll`: accepts an array of entities or an object in the shape of `Record<EntityId, T>`, and replaces the existing entity contents with the values in the array.
209209
- `removeOne`: accepts a single entity ID value, and removes the entity with that ID if it exists.
210210
- `removeMany`: accepts an array of entity ID values, and removes each entity with those IDs if they exist.
211+
- `removeAll`: removes all entities from the entity state object.
211212
- `updateOne`: accepts an "update object" containing an entity ID and an object containing one or more new field values to update inside a `changes` field, and performs a shallow update on the corresponding entity.
212213
- `updateMany`: accepts an array of update objects, and performs shallow updates on all corresponding entities.
213214
- `upsertOne`: accepts a single entity. If an entity with that ID exists, it will perform a shallow update and the specified fields will be merged into the existing entity, with any matching fields overwriting the existing values. If the entity does not exist, it will be added.

docs/api/otherExports.mdx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,32 @@ console.log(nanoid())
2222
// 'dgPXxUz_6fWIQBD8XmiSy'
2323
```
2424

25+
### `miniSerializeError`
26+
27+
The default error serialization function used by `createAsyncThunk`, based on https://github.com/sindresorhus/serialize-error. If its argument is an object (such as an `Error` instance), it returns a plain JS `SerializedError` object that copies over any of the listed fields. Otherwise, it returns a stringified form of the value: `{ message: String(value) }`.
28+
29+
```ts no-transpile
30+
export interface SerializedError {
31+
name?: string
32+
message?: string
33+
stack?: string
34+
code?: string
35+
}
36+
37+
export function miniSerializeError(value: any): SerializedError {}
38+
```
39+
40+
### `copyWithStructuralSharing`
41+
42+
A utility that will recursively merge two similar objects together, preserving existing references if the values appear to be the same. This is used internally to help ensure that re-fetched data keeps using the same references unless the new data has actually changed, to avoid unnecessary re-renders. Otherwise, every re-fetch would likely cause the entire dataset to be replaced and all consuming components to always re-render.
43+
44+
If either of the inputs are not plain JS objects or arrays, the new value is returned.
45+
46+
```ts no-transpile
47+
export function copyWithStructuralSharing<T>(oldObj: any, newObj: T): T
48+
export function copyWithStructuralSharing(oldObj: any, newObj: any): any {}
49+
```
50+
2551
## Exports from Other Libraries
2652

2753
### `createNextState`

docs/api/serializabilityMiddleware.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ interface SerializableStateInvariantMiddlewareOptions {
5555
* Defaults to 32ms.
5656
*/
5757
warnAfter?: number
58+
59+
/**
60+
* Opt out of checking state, but continue checking actions
61+
*/
62+
ignoreState?: boolean
5863
}
5964
```
6065

docs/introduction/getting-started.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The **Redux Toolkit** package is intended to be the standard way to write [Redux
2020
- "I have to add a lot of packages to get Redux to do anything useful"
2121
- "Redux requires too much boilerplate code"
2222

23-
We can't solve every use case, but in the spirit of [`create-react-app`](https://github.com/facebook/create-react-app) and [`apollo-boost`](https://dev-blog.apollodata.com/zero-config-graphql-state-management-27b1f1b3c2c3), we can try to provide some tools that abstract over the setup process and handle the most common use cases, as well as include some useful utilities that will let the user simplify their application code.
23+
We can't solve every use case, but in the spirit of [`create-react-app`](https://github.com/facebook/create-react-app) and [`apollo-boost`](https://www.apollographql.com/blog/announcement/frontend/zero-config-graphql-state-management/), we can try to provide some tools that abstract over the setup process and handle the most common use cases, as well as include some useful utilities that will let the user simplify their application code.
2424

2525
Redux Toolkit also includes a powerful data fetching and caching capability that we've dubbed ["RTK Query"](#rtk-query). It's included in the package as a separate set of entry points. It's optional, but can eliminate the need to hand-write data fetching logic yourself.
2626

@@ -49,7 +49,11 @@ Redux Toolkit is available as a package on NPM for use with a module bundler or
4949
```bash
5050
# NPM
5151
npm install @reduxjs/toolkit
52+
```
53+
54+
or
5255

56+
```bash
5357
# Yarn
5458
yarn add @reduxjs/toolkit
5559
```
@@ -71,9 +75,9 @@ Redux Toolkit includes these APIs:
7175

7276
## RTK Query
7377

74-
**RTK Query** is provided as an optional addon within the `@reduxjs/toolkit` package. It is purpose-built to solve the use case of data fetching and caching, supplying a compact, but powerful toolset to define an API interface layer for your app. It is intended to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself.
78+
[**RTK Query**](../rtk-query/overview.md) is provided as an optional addon within the `@reduxjs/toolkit` package. It is purpose-built to solve the use case of data fetching and caching, supplying a compact, but powerful toolset to define an API interface layer for your app. It is intended to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself.
7579

76-
RTK Query is built on top of the Redux Toolkit core for it's implementation, using [Redux](https://redux.js.org/) internally for it's architecture. Although knowledge of Redux and RTK are not required to use RTK Query, you should explore all of the additional global store management capabilities they provide, as well as installing the [Redux DevTools browser extension](https://github.com/reduxjs/redux-devtools), which works flawlessly with RTK Query to traverse and replay a timeline of your request & cache behavior.
80+
RTK Query is built on top of the Redux Toolkit core for its implementation, using [Redux](https://redux.js.org/) internally for its architecture. Although knowledge of Redux and RTK are not required to use RTK Query, you should explore all of the additional global store management capabilities they provide, as well as installing the [Redux DevTools browser extension](https://github.com/reduxjs/redux-devtools), which works flawlessly with RTK Query to traverse and replay a timeline of your request & cache behavior.
7781

7882
RTK Query is included within the installation of the core Redux Toolkit package. It is available via either of the two entry points below:
7983

@@ -89,11 +93,13 @@ import { createApi } from '@reduxjs/toolkit/query/react'
8993

9094
RTK Query includes these APIs:
9195

92-
- [`createApi()`](../rtk-query/api/createApi.mdx): The core of RTK Query's functionality. It allows you to define a set of endpoints describe how to retrieve data from a series of endpoints, including configuration of how to fetch and transform that data.
93-
- [`fetchBaseQuery()`](../rtk-query/api/fetchBaseQuery.mdx): A small wrapper around [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) that aims to simply requests. Intended as the recommended `baseQuery` to be used in `createApi` for the majority of users.
96+
- [`createApi()`](../rtk-query/api/createApi.mdx): The core of RTK Query's functionality. It allows you to define a set of endpoints describe how to retrieve data from a series of endpoints, including configuration of how to fetch and transform that data. In most cases, you should use this once per app, with "one API slice per base URL" as a rule of thumb.
97+
- [`fetchBaseQuery()`](../rtk-query/api/fetchBaseQuery.mdx): A small wrapper around [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) that aims to simplify requests. Intended as the recommended `baseQuery` to be used in `createApi` for the majority of users.
9498
- [`<ApiProvider />`](../rtk-query/api/ApiProvider.mdx): Can be used as a `Provider` if you **do not already have a Redux store**.
9599
- [`setupListeners()`](../rtk-query/api/setupListeners.mdx): A utility used to enable `refetchOnMount` and `refetchOnReconnect` behaviors.
96100

101+
See the [**RTK Query Overview**](../rtk-query/overview.md) page for more details on what RTK Query is, what problems it solves, and how to use it.
102+
97103
## Learn Redux
98104

99105
We have a variety of resources available to help you learn Redux.

docs/rtk-query/api/ApiProvider.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Using this together with an existing Redux store will cause them to conflict wit
2020
### Example
2121

2222
<iframe
23-
src="https://codesandbox.io/embed/github/reduxjs/redux-toolkit/tree/feature/v1.6-integration/examples/query/react/with-apiprovider?fontsize=12&hidenavigation=1&module=%2Fsrc%2FApp.tsx&theme=dark"
23+
src="https://codesandbox.io/embed/github/reduxjs/redux-toolkit/tree/master/examples/query/react/with-apiprovider?fontsize=12&runonclick=1&hidenavigation=1&module=%2Fsrc%2FApp.tsx&theme=dark"
2424
style={{
2525
width: '100%',
2626
height: '800px',

docs/rtk-query/api/createApi.mdx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ hide_title: true
1111

1212
`createApi` is the core of RTK Query's functionality. It allows you to define a set of endpoints describe how to retrieve data from a series of endpoints, including configuration of how to fetch and transform that data. It generates [an "API slice" structure](./created-api/overview.mdx) that contains Redux logic (and optionally React hooks) that encapsulate the data fetching and caching process for you.
1313

14+
:::tip
15+
16+
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`. This allows you to effectively take advantage of [automated re-fetching](../usage/automated-refetching.mdx) by defining [tag](../usage/automated-refetching.mdx#tags) relationships across endpoints.
17+
18+
For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See [code splitting](../usage/code-splitting.mdx) for how you can use the `injectEndpoints` property to inject API endpoints from other files into a single API slice definition.
19+
20+
:::
21+
1422
```ts title="Example: src/services/pokemon.ts"
1523
// file: src/services/types.ts noEmit
1624
export type Pokemon = {}
@@ -484,6 +492,46 @@ async function onQueryStarted(
484492
): Promise<void>
485493
```
486494

495+
```ts title="onQueryStarted query lifecycle example"
496+
// file: notificationsSlice.ts noEmit
497+
export const messageCreated = (msg: string) => ({
498+
type: 'notifications/messageCreated',
499+
payload: msg,
500+
})
501+
502+
// file: api.ts
503+
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
504+
import { messageCreated } from './notificationsSlice'
505+
506+
export interface Post {
507+
id: number
508+
name: string
509+
}
510+
511+
const api = createApi({
512+
baseQuery: fetchBaseQuery({
513+
baseUrl: '/',
514+
}),
515+
endpoints: (build) => ({
516+
getPost: build.query<Post, number>({
517+
query: (id) => `post/${id}`,
518+
async onQueryStarted(id, { dispatch, queryFulfilled }) {
519+
// `onStart` side-effect
520+
dispatch(messageCreated('Fetching post...'))
521+
try {
522+
const { data } = await queryFulfilled
523+
// `onSuccess` side-effect
524+
dispatch(messageCreated('Post received!'))
525+
} catch (err) {
526+
// `onError` side-effect
527+
dispatch(messageCreated('Error fetching post!'))
528+
}
529+
},
530+
}),
531+
}),
532+
})
533+
```
534+
487535
### `onCacheEntryAdded`
488536

489537
_(optional)_

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ This section documents the contents of that API structure, with the different fi
1717

1818
:::tip
1919

20-
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`.
20+
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`. This allows you to effectively take advantage of [automated re-fetching](../../usage/automated-refetching.mdx) by defining [tag](../../usage/automated-refetching.mdx#tags) relationships across endpoints.
21+
22+
For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See [code splitting](../../usage/code-splitting.mdx) for how you can use the `injectEndpoints` property to inject API endpoints from other files into a single API slice definition.
2123

2224
:::
2325

docs/rtk-query/comparison.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ In general, the main reasons to use RTK Query are:
2727
RTK Query has some unique API design aspects and capabilities that are worth considering.
2828

2929
- With React Query and SWR, you usually define your hooks yourself, and you can do that all over the place and on the fly. With RTK Query, you do so in one central place by defining an "API slice" with multiple endpoints ahead of time. This allows for a more tightly integrated model of mutations automatically invalidating/refetching queries on trigger.
30-
- With the endpoint [matcher functionality](./api/created-api/endpoints#matchers): Every request is automatically is visible to your Redux reducers and can easily update the global application state if necessary ([see example](https://github.com/reduxjs/redux-toolkit/issues/958#issuecomment-809570419)).
30+
- Because RTK Query dispatches normal Redux actions as requests are processed, all actions are visible in the Redux DevTools. Additionally, every request is automatically is visible to your Redux reducers and can easily update the global application state if necessary ([see example](https://github.com/reduxjs/redux-toolkit/issues/958#issuecomment-809570419)). You can use the endpoint [matcher functionality](./api/created-api/endpoints#matchers) to do additional processing of cache-related actions in your own reducers.
31+
- Like Redux itself, the main RTK Query functionality is UI-agnostic and can be used with any UI layer
3132
- You can easily invalidate entities or patch existing query data (via `util.updateQueryData`) from middleware.
3233
- RTK Query enables [streaming cache updates](./usage/streaming-updates.mdx), such as updating the initial fetched data as messages are received over a websocket, and has built in support for [optimistic updates](./usage/optimistic-updates.mdx) as well.
33-
- Like Redux itself, the main RTK Query functionality is UI-agnostic and can be used with any UI layer
3434
- RTK Query ships a very tiny and flexible fetch wrapper: [`fetchBaseQuery`](./api/fetchBaseQuery.mdx). It's also very easy to [swap our client with your own](./usage/customizing-queries.mdx), such as using `axios`, `redaxios`, or something custom.
35-
- RTK Query has [a (currently experimental) code-gen tool](https://github.com/rtk-incubator/rtk-query-codegen) that will take an OpenAPI spec and give you a typed API client, as well as provide methods for enhancing the generated client after the fact.
35+
- RTK Query has [a (currently experimental) code-gen tool](https://github.com/rtk-incubator/rtk-query-codegen) that will take an OpenAPI spec or GraphQL schema and give you a typed API client, as well as provide methods for enhancing the generated client after the fact.
3636

3737
## Tradeoffs
3838

@@ -45,6 +45,19 @@ RTK Query deliberately **does _not_ implement a cache that would deduplicate ide
4545
- In many cases, simply refetching data when it's invalidated works well and is easier to understand
4646
- At a minimum, RTKQ can help solve the general use case of "fetch some data", which is a big pain point for a lot of people
4747

48+
### Bundle Size
49+
50+
RTK Query adds a fixed one-time amount to your app's bundle size. Since RTK Query builds on top of Redux Toolkit and React-Redux, the added size varies depending on whether you are already using those in your app. The estimated min+gzip bundle sizes are:
51+
52+
- If you are using RTK already: ~9kb for RTK Query and ~2kb for the hooks.
53+
- If you are not using RTK already:
54+
- Without React: 17 kB for RTK+dependencies+RTK Query
55+
- With React: 19kB + React-Redux, which is a peer dependency
56+
57+
Adding additional endpoint definitions should only increase size based on the actual code inside the `endpoints` definitions, which will typically be just a few bytes.
58+
59+
The functionality included in RTK Query quickly pays for the added bundle size, and the elimination of hand-written data fetching logic should be a net improvement in size for most meaningful applications.
60+
4861
## Comparing Feature Sets
4962

5063
It's worth comparing the feature sets of all these tools to get a sense of their similarities and differences.

0 commit comments

Comments
 (0)