UNPKG

16.8 kBTypeScriptView Raw
1import { useEffect } from 'react';
2import { QueryStatus } from '@reduxjs/toolkit/query';
3import type { QuerySubState, SubscriptionOptions, QueryKeys } from '@reduxjs/toolkit/dist/query/core/apiState';
4import type { EndpointDefinitions, MutationDefinition, QueryDefinition, QueryArgFrom } from '@reduxjs/toolkit/dist/query/endpointDefinitions';
5import type { MutationResultSelectorResult, SkipToken } from '@reduxjs/toolkit/dist/query/core/buildSelectors';
6import type { QueryActionCreatorResult, MutationActionCreatorResult } from '@reduxjs/toolkit/dist/query/core/buildInitiate';
7import type { Api } from '@reduxjs/toolkit/dist/query/apiTypes';
8import type { Id, NoInfer, Override } from '@reduxjs/toolkit/dist/query/tsHelpers';
9import type { CoreModule, PrefetchOptions } from '@reduxjs/toolkit/dist/query/core/module';
10import type { ReactHooksModuleOptions } from './module';
11import type { UninitializedValue } from './constants';
12export declare const useIsomorphicLayoutEffect: typeof useEffect;
13export interface QueryHooks<Definition extends QueryDefinition<any, any, any, any, any>> {
14 useQuery: UseQuery<Definition>;
15 useLazyQuery: UseLazyQuery<Definition>;
16 useQuerySubscription: UseQuerySubscription<Definition>;
17 useLazyQuerySubscription: UseLazyQuerySubscription<Definition>;
18 useQueryState: UseQueryState<Definition>;
19}
20export interface MutationHooks<Definition extends MutationDefinition<any, any, any, any, any>> {
21 useMutation: UseMutation<Definition>;
22}
23/**
24 * A React hook that automatically triggers fetches of data from an endpoint, 'subscribes' the component to the cached data, and reads the request status and cached data from the Redux store. The component will re-render as the loading status changes and the data becomes available.
25 *
26 * The query arg is used as a cache key. Changing the query arg will tell the hook to re-fetch the data if it does not exist in the cache already, and the hook will return the data for that query arg once it's available.
27 *
28 * This hook combines the functionality of both [`useQueryState`](#usequerystate) and [`useQuerySubscription`](#usequerysubscription) together, and is intended to be used in the majority of situations.
29 *
30 * #### Features
31 *
32 * - Automatically triggers requests to retrieve data based on the hook argument and whether cached data exists by default
33 * - 'Subscribes' the component to keep cached data in the store, and 'unsubscribes' when the component unmounts
34 * - Accepts polling/re-fetching options to trigger automatic re-fetches when the corresponding criteria is met
35 * - Returns the latest request status and cached data from the Redux store
36 * - Re-renders as the request status changes and data becomes available
37 */
38export declare type UseQuery<D extends QueryDefinition<any, any, any, any>> = <R extends Record<string, any> = UseQueryStateDefaultResult<D>>(arg: QueryArgFrom<D> | SkipToken, options?: UseQuerySubscriptionOptions & UseQueryStateOptions<D, R>) => UseQueryStateResult<D, R> & ReturnType<UseQuerySubscription<D>>;
39interface UseQuerySubscriptionOptions extends SubscriptionOptions {
40 /**
41 * Prevents a query from automatically running.
42 *
43 * @remarks
44 * When `skip` is true (or `skipToken` is passed in as `arg`):
45 *
46 * - **If the query has cached data:**
47 * * The cached data **will not be used** on the initial load, and will ignore updates from any identical query until the `skip` condition is removed
48 * * The query will have a status of `uninitialized`
49 * * If `skip: false` is set after skipping the initial load, the cached result will be used
50 * - **If the query does not have cached data:**
51 * * The query will have a status of `uninitialized`
52 * * The query will not exist in the state when viewed with the dev tools
53 * * The query will not automatically fetch on mount
54 * * The query will not automatically run when additional components with the same query are added that do run
55 *
56 * @example
57 * ```tsx
58 * // codeblock-meta title="Skip example"
59 * const Pokemon = ({ name, skip }: { name: string; skip: boolean }) => {
60 * const { data, error, status } = useGetPokemonByNameQuery(name, {
61 * skip,
62 * });
63 *
64 * return (
65 * <div>
66 * {name} - {status}
67 * </div>
68 * );
69 * };
70 * ```
71 */
72 skip?: boolean;
73 /**
74 * Defaults to `false`. This setting allows you to control whether if a cached result is already available, RTK Query will only serve a cached result, or if it should `refetch` when set to `true` or if an adequate amount of time has passed since the last successful query result.
75 * - `false` - Will not cause a query to be performed _unless_ it does not exist yet.
76 * - `true` - Will always refetch when a new subscriber to a query is added. Behaves the same as calling the `refetch` callback or passing `forceRefetch: true` in the action creator.
77 * - `number` - **Value is in seconds**. If a number is provided and there is an existing query in the cache, it will compare the current time vs the last fulfilled timestamp, and only refetch if enough time has elapsed.
78 *
79 * If you specify this option alongside `skip: true`, this **will not be evaluated** until `skip` is false.
80 */
81 refetchOnMountOrArgChange?: boolean | number;
82}
83/**
84 * A React hook that automatically triggers fetches of data from an endpoint, and 'subscribes' the component to the cached data.
85 *
86 * The query arg is used as a cache key. Changing the query arg will tell the hook to re-fetch the data if it does not exist in the cache already.
87 *
88 * Note that this hook does not return a request status or cached data. For that use-case, see [`useQuery`](#usequery) or [`useQueryState`](#usequerystate).
89 *
90 * #### Features
91 *
92 * - Automatically triggers requests to retrieve data based on the hook argument and whether cached data exists by default
93 * - 'Subscribes' the component to keep cached data in the store, and 'unsubscribes' when the component unmounts
94 * - Accepts polling/re-fetching options to trigger automatic re-fetches when the corresponding criteria is met
95 */
96export declare type UseQuerySubscription<D extends QueryDefinition<any, any, any, any>> = (arg: QueryArgFrom<D> | SkipToken, options?: UseQuerySubscriptionOptions) => Pick<QueryActionCreatorResult<D>, 'refetch'>;
97export declare type UseLazyQueryLastPromiseInfo<D extends QueryDefinition<any, any, any, any>> = {
98 lastArg: QueryArgFrom<D>;
99};
100/**
101 * A React hook similar to [`useQuery`](#usequery), but with manual control over when the data fetching occurs.
102 *
103 * This hook includes the functionality of [`useLazyQuerySubscription`](#uselazyquerysubscription).
104 *
105 * #### Features
106 *
107 * - Manual control over firing a request to retrieve data
108 * - 'Subscribes' the component to keep cached data in the store, and 'unsubscribes' when the component unmounts
109 * - Returns the latest request status and cached data from the Redux store
110 * - Re-renders as the request status changes and data becomes available
111 * - Accepts polling/re-fetching options to trigger automatic re-fetches when the corresponding criteria is met and the fetch has been manually called at least once
112 *
113 * #### Note
114 *
115 * When the trigger function returned from a LazyQuery, it always initiates a new request to the server even if there is cached data. Set `preferCacheValue`(the second argument to the function) as true if you want it to use cache.
116 */
117export declare type UseLazyQuery<D extends QueryDefinition<any, any, any, any>> = <R = UseQueryStateDefaultResult<D>>(options?: SubscriptionOptions & Omit<UseQueryStateOptions<D, R>, 'skip'>) => [
118 LazyQueryTrigger<D>,
119 UseQueryStateResult<D, R>,
120 UseLazyQueryLastPromiseInfo<D>
121];
122export declare type LazyQueryTrigger<D extends QueryDefinition<any, any, any, any>> = {
123 /**
124 * Triggers a lazy query.
125 *
126 * By default, this will start a new request even if there is already a value in the cache.
127 * If you want to use the cache value and only start a request if there is no cache value, set the second argument to `true`.
128 */
129 (arg: QueryArgFrom<D>, preferCacheValue?: boolean): void;
130};
131/**
132 * A React hook similar to [`useQuerySubscription`](#usequerysubscription), but with manual control over when the data fetching occurs.
133 *
134 * Note that this hook does not return a request status or cached data. For that use-case, see [`useLazyQuery`](#uselazyquery).
135 *
136 * #### Features
137 *
138 * - Manual control over firing a request to retrieve data
139 * - 'Subscribes' the component to keep cached data in the store, and 'unsubscribes' when the component unmounts
140 * - Accepts polling/re-fetching options to trigger automatic re-fetches when the corresponding criteria is met and the fetch has been manually called at least once
141 */
142export declare type UseLazyQuerySubscription<D extends QueryDefinition<any, any, any, any>> = (options?: SubscriptionOptions) => [(arg: QueryArgFrom<D>) => void, QueryArgFrom<D> | UninitializedValue];
143export declare type QueryStateSelector<R extends Record<string, any>, D extends QueryDefinition<any, any, any, any>> = (state: UseQueryStateDefaultResult<D>) => R;
144/**
145 * A React hook that reads the request status and cached data from the Redux store. The component will re-render as the loading status changes and the data becomes available.
146 *
147 * Note that this hook does not trigger fetching new data. For that use-case, see [`useQuery`](#usequery) or [`useQuerySubscription`](#usequerysubscription).
148 *
149 * #### Features
150 *
151 * - Returns the latest request status and cached data from the Redux store
152 * - Re-renders as the request status changes and data becomes available
153 */
154export declare type UseQueryState<D extends QueryDefinition<any, any, any, any>> = <R = UseQueryStateDefaultResult<D>>(arg: QueryArgFrom<D> | SkipToken, options?: UseQueryStateOptions<D, R>) => UseQueryStateResult<D, R>;
155export declare type UseQueryStateOptions<D extends QueryDefinition<any, any, any, any>, R extends Record<string, any>> = {
156 /**
157 * Prevents a query from automatically running.
158 *
159 * @remarks
160 * When skip is true:
161 *
162 * - **If the query has cached data:**
163 * * The cached data **will not be used** on the initial load, and will ignore updates from any identical query until the `skip` condition is removed
164 * * The query will have a status of `uninitialized`
165 * * If `skip: false` is set after skipping the initial load, the cached result will be used
166 * - **If the query does not have cached data:**
167 * * The query will have a status of `uninitialized`
168 * * The query will not exist in the state when viewed with the dev tools
169 * * The query will not automatically fetch on mount
170 * * The query will not automatically run when additional components with the same query are added that do run
171 *
172 * @example
173 * ```ts
174 * // codeblock-meta title="Skip example"
175 * const Pokemon = ({ name, skip }: { name: string; skip: boolean }) => {
176 * const { data, error, status } = useGetPokemonByNameQuery(name, {
177 * skip,
178 * });
179 *
180 * return (
181 * <div>
182 * {name} - {status}
183 * </div>
184 * );
185 * };
186 * ```
187 */
188 skip?: boolean;
189 /**
190 * `selectFromResult` allows you to get a specific segment from a query result in a performant manner.
191 * When using this feature, the component will not rerender unless the underlying data of the selected item has changed.
192 * If the selected item is one element in a larger collection, it will disregard changes to elements in the same collection.
193 *
194 * @example
195 * ```ts
196 * // codeblock-meta title="Using selectFromResult to extract a single result"
197 * function PostsList() {
198 * const { data: posts } = api.useGetPostsQuery();
199 *
200 * return (
201 * <ul>
202 * {posts?.data?.map((post) => (
203 * <PostById key={post.id} id={post.id} />
204 * ))}
205 * </ul>
206 * );
207 * }
208 *
209 * function PostById({ id }: { id: number }) {
210 * // Will select the post with the given id, and will only rerender if the given posts data changes
211 * const { post } = api.useGetPostsQuery(undefined, {
212 * selectFromResult: ({ data }) => ({ post: data?.find((post) => post.id === id) }),
213 * });
214 *
215 * return <li>{post?.name}</li>;
216 * }
217 * ```
218 */
219 selectFromResult?: QueryStateSelector<R, D>;
220};
221export declare type UseQueryStateResult<_ extends QueryDefinition<any, any, any, any>, R> = NoInfer<R>;
222declare type UseQueryStateBaseResult<D extends QueryDefinition<any, any, any, any>> = QuerySubState<D> & {
223 /**
224 * Query has not started yet.
225 */
226 isUninitialized: false;
227 /**
228 * Query is currently loading for the first time. No data yet.
229 */
230 isLoading: false;
231 /**
232 * Query is currently fetching, but might have data from an earlier request.
233 */
234 isFetching: false;
235 /**
236 * Query has data from a successful load.
237 */
238 isSuccess: false;
239 /**
240 * Query is currently in "error" state.
241 */
242 isError: false;
243};
244declare type UseQueryStateDefaultResult<D extends QueryDefinition<any, any, any, any>> = Id<Override<Extract<UseQueryStateBaseResult<D>, {
245 status: QueryStatus.uninitialized;
246}>, {
247 isUninitialized: true;
248}> | Override<UseQueryStateBaseResult<D>, {
249 isLoading: true;
250 isFetching: boolean;
251 data: undefined;
252} | ({
253 isSuccess: true;
254 isFetching: boolean;
255 error: undefined;
256} & Required<Pick<UseQueryStateBaseResult<D>, 'data' | 'fulfilledTimeStamp'>>) | ({
257 isError: true;
258} & Required<Pick<UseQueryStateBaseResult<D>, 'error'>>)>> & {
259 /**
260 * @deprecated will be removed in the next version
261 * please use the `isLoading`, `isFetching`, `isSuccess`, `isError`
262 * and `isUninitialized` flags instead
263 */
264 status: QueryStatus;
265};
266export declare type MutationStateSelector<R extends Record<string, any>, D extends MutationDefinition<any, any, any, any>> = (state: MutationResultSelectorResult<D>) => R;
267export declare type UseMutationStateOptions<D extends MutationDefinition<any, any, any, any>, R extends Record<string, any>> = {
268 selectFromResult?: MutationStateSelector<R, D>;
269};
270export declare type UseMutationStateResult<D extends MutationDefinition<any, any, any, any>, R> = NoInfer<R> & {
271 originalArgs?: QueryArgFrom<D>;
272};
273/**
274 * A React hook that lets you trigger an update request for a given endpoint, and subscribes the component to read the request status from the Redux store. The component will re-render as the loading status changes.
275 *
276 * #### Features
277 *
278 * - Manual control over firing a request to alter data on the server or possibly invalidate the cache
279 * - 'Subscribes' the component to keep cached data in the store, and 'unsubscribes' when the component unmounts
280 * - Returns the latest request status and cached data from the Redux store
281 * - Re-renders as the request status changes and data becomes available
282 */
283export declare type UseMutation<D extends MutationDefinition<any, any, any, any>> = <R extends Record<string, any> = MutationResultSelectorResult<D>>(options?: UseMutationStateOptions<D, R>) => [
284 (arg: QueryArgFrom<D>) => MutationActionCreatorResult<D>,
285 UseMutationStateResult<D, R>
286];
287/**
288 *
289 * @param opts.api - An API with defined endpoints to create hooks for
290 * @param opts.moduleOptions.batch - The version of the `batchedUpdates` function to be used
291 * @param opts.moduleOptions.useDispatch - The version of the `useDispatch` hook to be used
292 * @param opts.moduleOptions.useSelector - The version of the `useSelector` hook to be used
293 * @returns An object containing functions to generate hooks based on an endpoint
294 */
295export declare function buildHooks<Definitions extends EndpointDefinitions>({ api, moduleOptions: { batch, useDispatch, useSelector, useStore }, }: {
296 api: Api<any, Definitions, any, any, CoreModule>;
297 moduleOptions: Required<ReactHooksModuleOptions>;
298}): {
299 buildQueryHooks: (name: string) => QueryHooks<any>;
300 buildMutationHook: (name: string) => UseMutation<any>;
301 usePrefetch: <EndpointName extends QueryKeys<Definitions>>(endpointName: EndpointName, defaultOptions?: PrefetchOptions | undefined) => (arg: any, options?: PrefetchOptions | undefined) => void;
302};
303export {};