Skip to content

Commit de5ee76

Browse files
Conflict Resolved
2 parents 7689ac6 + af3e75b commit de5ee76

File tree

123 files changed

+25754
-29584
lines changed

Some content is hidden

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

123 files changed

+25754
-29584
lines changed

.github/workflows/tests.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,21 @@ jobs:
114114
- name: Erase path aliases
115115
run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json
116116

117-
- name: Run tests, against dist
118-
env:
119-
TEST_DIST: true
120-
run: yarn test
121-
122117
- name: Run type tests with `moduleResolution Bundler`
123118
run: rm -rf dist && yarn tsc -p . --moduleResolution Bundler --module ESNext --noEmit false --declaration --emitDeclarationOnly --outDir dist --target ESNext && rm -rf dist
124119

120+
- name: Ensure there's no dist folder
121+
run: rm -rf dist
122+
123+
- name: Change RTK package name to ensure node_modules is used
124+
run: sed -i -e 's|@reduxjs/toolkit|@reduxjs/toolkit-test|' ./package.json
125+
126+
- name: Run tests, against installed artifact
127+
env:
128+
TEST_DIST: true
129+
working-directory: ./packages/toolkit
130+
run: ../../node_modules/.bin/vitest --run --typecheck
131+
125132
test-types:
126133
name: 'Test Types: TS ${{ matrix.ts }} and React ${{ matrix.react.version }}'
127134

@@ -241,12 +248,13 @@ jobs:
241248
- name: Show installed RTK versions
242249
run: yarn info @reduxjs/toolkit && yarn why @reduxjs/toolkit
243250

244-
- name: Set up JDK 17 for React Native build
251+
- name: Set up JDK 21 for React Native build
245252
if: matrix.example == 'react-native' || matrix.example == 'expo'
246253
uses: actions/setup-java@v4
247254
with:
248-
java-version: '17.x'
255+
java-version: '21.x'
249256
distribution: 'temurin'
257+
cache: 'gradle'
250258

251259
- name: Build example
252260
env:

docs/api/createEntityAdapter.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ If `updateMany()` is called with multiple updates targeted to the same ID, they
377377

378378
For both `updateOne()` and `updateMany()`, changing the ID of one existing entity to match the ID of a second existing entity will cause the first to replace the second completely.
379379

380+
Additionally, if there is no item for that ID, the update will be silently ignored.
381+
380382
## Examples
381383

382384
Exercising several of the CRUD methods and selectors:

docs/rtk-query/api/createApi.mdx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,32 @@ Query endpoints (defined with `build.query()`) are used to cache data fetched fr
153153
You must specify either a `query` field (which will use the API's `baseQuery` to make a request), or a `queryFn` function with your own async logic. All other fields are optional.
154154
155155
```ts title="Query endpoint definition" no-transpile
156+
export type FullTagDescription<TagType> = {
157+
type: TagType
158+
id?: number | string
159+
}
160+
export type TagDescription<TagType> = TagType | FullTagDescription<TagType>
161+
162+
type TagDescriptionArray<TagTypes extends string> = ReadonlyArray<
163+
TagDescription<TagTypes> | undefined | null
164+
>
165+
166+
export type ResultDescription<
167+
TagTypes extends string,
168+
ResultType,
169+
QueryArg,
170+
ErrorType,
171+
MetaType,
172+
> =
173+
| TagDescriptionArray<TagTypes>
174+
| (
175+
result: ResultType | undefined,
176+
error: ErrorType | undefined,
177+
arg: QueryArg,
178+
meta: MetaType,
179+
) => TagDescriptionArray<TagTypes>
180+
181+
156182
export type QueryDefinition<
157183
QueryArg,
158184
BaseQuery extends BaseQueryFn,
@@ -245,11 +271,12 @@ Infinite query endpoints (defined with `build.infiniteQuery()`) are used to cach
245271
For infinite query endpoints, there is a separation between the "query arg" used for the cache key, and the "page param" used to fetch a specific page. For example, a Pokemon API endpoint might have a string query arg like `"fire"` , but use a page number as the param to determine which page to fetch out of the results. The `query` and `queryFn` methods will receive a combined `{queryArg, pageParam}` object as the argument, rather than just the `queryArg` by itself.
246272
247273
```ts title="Infinite Query endpoint definition" no-transpile
248-
export type PageParamFunction<DataType, PageParam> = (
274+
export type PageParamFunction<DataType, PageParam, QueryArg> = (
249275
firstPage: DataType,
250276
allPages: Array<DataType>,
251277
firstPageParam: PageParam,
252278
allPageParams: Array<PageParam>,
279+
queryArg: QueryArg,
253280
) => PageParam | undefined | null
254281

255282
type InfiniteQueryCombinedArg<QueryArg, PageParam> = {
@@ -290,12 +317,12 @@ export type InfiniteQueryDefinition<
290317
* This function is required to automatically get the next cursor for infinite queries.
291318
* The result will also be used to determine the value of `hasNextPage`.
292319
*/
293-
getNextPageParam: PageParamFunction<DataType, PageParam>
320+
getNextPageParam: PageParamFunction<DataType, PageParam, QueryArg>
294321
/**
295322
* This function can be set to automatically get the previous cursor for infinite queries.
296323
* The result will also be used to determine the value of `hasPreviousPage`.
297324
*/
298-
getPreviousPageParam?: PageParamFunction<DataType, PageParam>
325+
getPreviousPageParam?: PageParamFunction<DataType, PageParam, QueryArg>
299326
/**
300327
* If specified, only keep this many pages in cache at once.
301328
* If additional pages are fetched, older pages in the other

docs/rtk-query/usage/code-splitting.mdx

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ description: 'RTK Query > Usage > Code Splitting: dynamic injection of endpoints
1010

1111
# Code Splitting
1212

13-
RTK Query makes it possible to trim down your initial bundle size by allowing you to inject additional endpoints after you've set up your initial service definition. This can be very beneficial for larger applications that may have _many_ endpoints.
13+
## Overview
1414

15-
`injectEndpoints` accepts a collection of endpoints, as well as an optional `overrideExisting` parameter.
15+
By default, an RTK Query API definition normally has all of the endpoint definitions in a single file. However, in larger applications this can result in very large files that may be harder to maintain. It also means that all of the relevant code is being imported right away.
1616

17-
Calling `injectEndpoints` will inject the endpoints into the original API, but also give you that same API with correct types for these endpoints back. (Unfortunately, it cannot modify the types for the original definition.)
17+
RTK Query allows dynamically injecting endpoint definitions into an existing API service object. This enables splitting up endpoints into multiple files for maintainability, as well as lazy-loading endpoint definitions and associated code to trim down initial bundle sizes. This can be very beneficial for larger applications that may have _many_ endpoints.
18+
19+
## Injecting Endpoints
20+
21+
`api.injectEndpoints` accepts a collection of endpoint definitions (same as `createApi`), as well as an optional `overrideExisting` parameter.
22+
23+
Calling `api.injectEndpoints` will inject the endpoints into the original API service object, modifying it immediately. It returns **the _same_ API service object reference**. If you're using TypeScript, the return value has the TS types for the new endpoints included. (Unfortunately, it cannot modify the types for the original API reference.)
1824

1925
A typical approach would be to have one empty central API slice definition:
2026

@@ -43,6 +49,7 @@ export const emptySplitApi = createApi({
4349
// file: extendedApi.ts
4450
import { emptySplitApi } from './emptySplitApi'
4551

52+
// NOTE: these are the _SAME_ API reference!
4653
const extendedApi = emptySplitApi.injectEndpoints({
4754
endpoints: (build) => ({
4855
example: build.query({
@@ -60,3 +67,59 @@ If you inject an endpoint that already exists and don't explicitly specify `over
6067
will not be overridden. In development mode, you will get a warning about this if `overrideExisting` is set to `false`,
6168
and an error will be throw if set to `'throw'`.
6269
:::
70+
71+
## Enhancing Endpoints
72+
73+
Sometimes you may also need to modify an existing API definition, such as adding additional tag types, or providing additional configuration options to a given endpoint.
74+
75+
`api.enhanceEndpoints` returns an updated and enhanced version of the API slice object, containing the combined endpoint definitions.
76+
77+
This is primarily useful for taking an API slice object that was code-generated from an API schema file like OpenAPI, and adding additional specific hand-written configuration for cache invalidation management on top of the generated endpoint definitions.
78+
79+
For example, `enhanceEndpoints` can be used to modify caching behavior by changing the values of `providesTags`, `invalidatesTags`, and `keepUnusedDataFor`:
80+
81+
```ts
82+
// file: api.ts noEmit
83+
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
84+
85+
export const api = createApi({
86+
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
87+
endpoints: (build) => ({
88+
getUserByUserId: build.query({
89+
query() {
90+
return ''
91+
},
92+
}),
93+
patchUserByUserId: build.mutation({
94+
query() {
95+
return ''
96+
},
97+
}),
98+
getUsers: build.query({
99+
query() {
100+
return ''
101+
},
102+
}),
103+
}),
104+
})
105+
106+
// file: enhanceEndpoints.ts
107+
import { api } from './api'
108+
109+
const enhancedApi = api.enhanceEndpoints({
110+
addTagTypes: ['User'],
111+
endpoints: {
112+
getUserByUserId: {
113+
providesTags: ['User'],
114+
},
115+
patchUserByUserId: {
116+
invalidatesTags: ['User'],
117+
},
118+
// alternatively, define a function which is called with the endpoint definition as an argument
119+
getUsers(endpoint) {
120+
endpoint.providesTags = ['User']
121+
endpoint.keepUnusedDataFor = 120
122+
},
123+
},
124+
})
125+
```

docs/rtk-query/usage/infinite-queries.mdx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,12 @@ ensure the infinite query can properly fetch the next page of data. Also, `initi
8282
`getNextPageParam` and `getPreviousPageParam` are user-defined, giving you flexibility to determine how those values are calculated:
8383

8484
```ts
85-
export type PageParamFunction<DataType, PageParam> = (
85+
export type PageParamFunction<DataType, PageParam, QueryArg> = (
8686
currentPage: DataType,
8787
allPages: DataType[],
8888
currentPageParam: PageParam,
8989
allPageParams: PageParam[],
90+
queryArg: QueryArg,
9091
) => PageParam | undefined | null
9192
```
9293
@@ -96,6 +97,8 @@ Since both actual page contents and page params are passed in, you can calculate
9697
9798
The "current" arguments will be either the last page for `getNextPageParam`, or the first page for `getPreviousPageParam`.
9899
100+
The list of arguments is the same as with React Query, but with the addition of `queryArg` at the end. (This is because React Query always has access to the query arg when you pass the options to its `useQuery` hook, but with RTK Query the endpoints are defined separately, so this makes the query arg accessible if you need it to calculate the page params.)
101+
99102
If there is no possible page to fetch in that direction, the callback should return `undefined`.
100103
101104
### Infinite Query Definition Example
@@ -119,14 +122,20 @@ const pokemonApi = createApi({
119122
// Optionally limit the number of cached pages
120123
maxPages: 3,
121124
// Must provide a `getNextPageParam` function
122-
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
123-
lastPageParam + 1,
125+
getNextPageParam: (
126+
lastPage,
127+
allPages,
128+
lastPageParam,
129+
allPageParams,
130+
queryArg,
131+
) => lastPageParam + 1,
124132
// Optionally provide a `getPreviousPageParam` function
125133
getPreviousPageParam: (
126134
firstPage,
127135
allPages,
128136
firstPageParam,
129137
allPageParams,
138+
queryArg,
130139
) => {
131140
return firstPageParam > 0 ? firstPageParam - 1 : undefined
132141
},

docs/usage/nextjs.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ export default function StoreProvider({
280280

281281
If you use Next.js's support for client side SPA-style navigation by using `next/navigation`, then when customers navigate from page to page only the route component will be re-rendered. This means that if you have a Redux store created and provided in the layout component it will be preserved across route changes. This is not a problem if you are only using the store for global, mutable data. However, if you are using the store for per-route data then you will need to reset the route-specific data in the store when the route changes.
282282

283-
Shown below is a `ProductName` example component that uses the Redux store to manage the mutable name of a product. The `ProductName` component part of a product detail route. In order to ensure that we have the correct name in the store we need to set the value in the store any time the `ProductName` component is initially rendered, which happens on any route change to the product detail route.
283+
Shown below is a `ProductName` example component that uses the Redux store to manage the mutable name of a product. The `ProductName` component is part of a product detail route. In order to ensure that we have the correct name in the store we need to set the value in the store any time the `ProductName` component is initially rendered, which happens on any route change to the product detail route.
284284

285285
```ts title="app/ProductName.tsx"
286286
// file: lib/features/product/productSlice.ts noEmit

examples/publish-ci/expo/.eslintrc.json

Lines changed: 0 additions & 41 deletions
This file was deleted.

examples/publish-ci/expo/.gitignore

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
# dependencies
44
node_modules/
5-
.yarn/
65

76
# Expo
87
.expo/
98
dist/
109
web-build/
10+
expo-env.d.ts
11+
build/
1112

1213
# Native
1314
*.orig.*
@@ -16,8 +17,8 @@ web-build/
1617
*.p12
1718
*.key
1819
*.mobileprovision
19-
android
20-
ios
20+
android/
21+
ios/
2122

2223
# Metro
2324
.metro-health-check*
@@ -36,3 +37,20 @@ yarn-error.*
3637

3738
# typescript
3839
*.tsbuildinfo
40+
41+
# testing
42+
/coverage
43+
44+
# Yarn
45+
.yarn/*
46+
!.yarn/patches
47+
!.yarn/plugins
48+
!.yarn/releases
49+
!.yarn/sdks
50+
!.yarn/versions
51+
52+
# IDE
53+
.vscode
54+
55+
.yalc/
56+
yalc.lock
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"arrowParens": "avoid",
3-
"bracketSameLine": true,
4-
"singleQuote": true,
5-
"trailingComma": "all"
3+
"semi": false,
4+
"singleQuote": true
65
}

0 commit comments

Comments
 (0)