@@ -2,25 +2,40 @@ import { SerializedError } from "@reduxjs/toolkit";
2
2
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query" ;
3
3
import { ReactElement } from "react" ;
4
4
5
+ /** Result of a RTK useQuery hook */
5
6
export type UseQueryResult < T > = {
6
7
// Base query state
7
- originalArgs ?: unknown ; // Arguments passed to the query
8
- data ?: T ; // The latest returned result regardless of hook arg, if present
9
- currentData ?: T ; // The latest returned result for the current hook arg, if present
10
- error ?: unknown ; // Error result if present
11
- requestId ?: string ; // A string generated by RTK Query
12
- endpointName ?: string ; // The name of the given endpoint for the query
13
- startedTimeStamp ?: number ; // Timestamp for when the query was initiated
14
- fulfilledTimeStamp ?: number ; // Timestamp for when the query was completed
8
+ /** Arguments passed to the query */
9
+ originalArgs ?: unknown ;
10
+ /** The latest returned result regardless of hook arg, if present */
11
+ data ?: T ;
12
+ /** The latest returned result for the current hook arg, if present */
13
+ currentData ?: T ;
14
+ /** Error result if present */
15
+ error ?: unknown ;
16
+ /** A string generated by RTK Query */
17
+ requestId ?: string ;
18
+ /** The name of the given endpoint for the query */
19
+ endpointName ?: string ;
20
+ /** Timestamp for when the query was initiated */
21
+ startedTimeStamp ?: number ;
22
+ /** Timestamp for when the query was completed */
23
+ fulfilledTimeStamp ?: number ;
15
24
16
25
// Derived request status booleans
17
- isUninitialized : boolean ; // Query has not started yet.
18
- isLoading : boolean ; // Query is currently loading for the first time. No data yet.
19
- isFetching : boolean ; // Query is currently fetching, but might have data from an earlier request.
20
- isSuccess : boolean ; // Query has data from a successful load.
21
- isError : boolean ; // Query is currently in an "error" state.
22
-
23
- refetch : ( ) => void ; // A function to force refetch the query
26
+ /** Query has not started yet */
27
+ isUninitialized : boolean ;
28
+ /** Query is currently loading for the first time. No data yet. */
29
+ isLoading : boolean ;
30
+ /** Query is currently fetching, but might have data from an earlier request. */
31
+ isFetching : boolean ;
32
+ /** Query has data from a successful load */
33
+ isSuccess : boolean ;
34
+ /** Query is currently in an "error" state */
35
+ isError : boolean ;
36
+
37
+ /** A function to force refetch the query */
38
+ refetch : ( ) => void ;
24
39
} ;
25
40
26
41
export type MakeDataRequired <
@@ -30,39 +45,45 @@ export type MakeDataRequired<
30
45
[ K in keyof T ] : T [ K ] & { data : NonNullable < T [ K ] [ "data" ] > } ;
31
46
} ;
32
47
48
+ /** Use: `(...args: OptionalGenericArg<T>) => void;`
49
+ * Allows either `T` or `none` for the parameter
50
+ */
51
+ export type OptionalGenericArg < T > = T extends never ? [ ] : [ T ] ;
52
+
33
53
export type LoaderTransformFunction <
34
54
QRU extends readonly UseQueryResult < unknown > [ ] ,
35
55
R extends unknown
36
56
> = ( queries : MakeDataRequired < QRU > ) => R ;
37
57
38
- export type OptionalGenericArg < T > = T extends never ? [ ] : [ T ] ;
39
-
40
58
export type CreateUseLoaderArgs <
41
59
QRU extends readonly UseQueryResult < unknown > [ ] ,
42
60
R extends unknown ,
43
61
A = never
44
62
> = {
63
+ /** Should return a list of RTK useQuery results.
64
+ * Example:
65
+ * ```typescript
66
+ * (args: Args) => [
67
+ * useGetPokemonQuery(args.pokemonId),
68
+ * useGetSomethingElse(args.someArg)
69
+ * ] as const
70
+ * ```
71
+ */
45
72
queries : ( ...args : OptionalGenericArg < A > ) => QRU ;
73
+ /** Transforms the output of the queries */
46
74
transform ?: LoaderTransformFunction < QRU , R > ;
47
75
} ;
48
76
49
77
export type UseLoader < A , R > = (
50
78
...args : OptionalGenericArg < A >
51
79
) => UseQueryResult < R > ;
52
80
53
- export type CreateLoaderType = <
54
- QRU extends readonly UseQueryResult < unknown > [ ] ,
55
- R extends unknown = MakeDataRequired < QRU > ,
56
- A = never
57
- > (
58
- createLoaderArgs : CreateUseLoaderArgs < QRU , R , A >
59
- ) => UseLoader < A , R > ;
60
-
61
81
export type ComponentWithLoaderData <
62
82
P extends Record < string , any > ,
63
83
R extends unknown
64
84
> = ( props : P , loaderData : R ) => ReactElement ;
65
85
86
+ /** Use: `InferLoaderData<typeof loader>`. Returns the return-value of the given loader's aggregated query. */
66
87
export type InferLoaderData < T > = T extends Loader <
67
88
any ,
68
89
infer X ,
@@ -79,28 +100,49 @@ export type Component<P extends Record<string, any>> = (
79
100
props : P
80
101
) => ReactElement ;
81
102
82
- export type WithLoaderArgs <
83
- P extends unknown ,
84
- R extends unknown ,
85
- A = never
86
- > = Loader < P , R , A > ;
87
-
88
103
export type WhileFetchingArgs <
89
104
P extends unknown ,
90
105
R extends unknown
91
106
> = {
107
+ /** Will be prepended before the component while the query is fetching */
92
108
prepend ?: ( props : P , data ?: R ) => ReactElement ;
109
+ /** Will be appended after the component while the query is fetching */
93
110
append ?: ( props : P , data ?: R ) => ReactElement ;
94
111
} ;
95
112
113
+ export type CustomLoaderProps < T = unknown > = {
114
+ /** What the loader requests be rendered while fetching data */
115
+ onFetching ?: React . ReactElement ;
116
+ /** What the loader requests be rendered while fetching data */
117
+ whileFetching ?: {
118
+ /** Should be appended to the success result while fetching */
119
+ append ?: React . ReactElement ;
120
+ /** Should be prepended to the success result while fetching */
121
+ prepend ?: React . ReactElement ;
122
+ } ;
123
+ /** What the loader requests be rendered when data is available */
124
+ onSuccess : ( data : T ) => React . ReactElement ;
125
+ /** What the loader requests be rendered when the query fails */
126
+ onError ?: (
127
+ error : SerializedError | FetchBaseQueryError
128
+ ) => JSX . Element ;
129
+ /** What the loader requests be rendered while loading data */
130
+ onLoading ?: React . ReactElement ;
131
+ /** The joined query for the loader */
132
+ query : UseQueryResult < T > ;
133
+ } ;
134
+
96
135
export type CreateLoaderArgs <
97
136
P extends unknown ,
98
137
QRU extends readonly UseQueryResult < unknown > [ ] ,
99
138
R extends unknown = MakeDataRequired < QRU > ,
100
139
A = never
101
140
> = Partial < CreateUseLoaderArgs < QRU , R , A > > & {
141
+ /** Generates an argument for the `queries` based on component props */
102
142
queriesArg ?: ( props : P ) => A ;
143
+ /** Determines what to render while loading (with no data to fallback on) */
103
144
onLoading ?: ( props : P ) => ReactElement ;
145
+ /** Determines what to render when query fails. */
104
146
onError ?: (
105
147
props : P ,
106
148
error : FetchBaseQueryError | SerializedError ,
@@ -111,17 +153,24 @@ export type CreateLoaderArgs<
111
153
props : P ,
112
154
renderBody : ( ) => ReactElement
113
155
) => ReactElement ;
156
+ /** Determines what to render besides success-result while query is fetching. */
114
157
whileFetching ?: WhileFetchingArgs < P , R > ;
158
+ /** The component to use to switch between rendering the different query states. */
159
+ loaderComponent ?: Component < CustomLoaderProps > ;
115
160
} ;
116
161
117
162
export type Loader <
118
163
P extends unknown ,
119
164
R extends unknown ,
120
165
A = never
121
166
> = {
167
+ /** A hook that runs all queries and returns aggregated result */
122
168
useLoader : UseLoader < A , R > ;
169
+ /** Generates an argument for the `queries` based on component props */
123
170
queriesArg ?: ( props : P ) => A ;
171
+ /** Determines what to render while loading (with no data to fallback on) */
124
172
onLoading ?: ( props : P ) => ReactElement ;
173
+ /** Determines what to render when query fails. */
125
174
onError ?: (
126
175
props : P ,
127
176
error : SerializedError | FetchBaseQueryError ,
@@ -132,7 +181,9 @@ export type Loader<
132
181
props : P ,
133
182
renderBody : ( ) => ReactElement
134
183
) => ReactElement ;
184
+ /** Determines what to render besides success-result while query is fetching. */
135
185
whileFetching ?: WhileFetchingArgs < P , R > ;
186
+ /** Returns a new `Loader` extended from this `Loader`, with given overrides. */
136
187
extend : <
137
188
QRUb extends readonly UseQueryResult < unknown > [ ] ,
138
189
Pb extends unknown = P ,
@@ -143,4 +194,14 @@ export type Loader<
143
194
> (
144
195
newLoader : Partial < CreateLoaderArgs < Pb , QRUb , Rb , Ab > >
145
196
) => Loader < Pb , Rb , Ab > ;
197
+ /** The component to use to switch between rendering the different query states. */
198
+ LoaderComponent : Component < CustomLoaderProps > ;
146
199
} ;
200
+
201
+ /** Legacy/unused, for backwards compatibility */
202
+
203
+ export type WithLoaderArgs <
204
+ P extends unknown ,
205
+ R extends unknown ,
206
+ A = never
207
+ > = Loader < P , R , A > ;
0 commit comments