API hook factories
The two factories turn an existing service object's asynchronous methods into stable hook names: getUser becomes useGetUser. Create the hook collection outside rendering. Both preserve the service's this binding and inspect own methods and its prototype chain, with the nearest property winning.
| Factory / utility | Contract |
|---|---|
createExecuteApiHooks({ api }) | Each hook takes executor options and returns state plus execute(...originalParameters): Promise<PromiseState>. No automatic invocation. |
createQueryApiHooks({ api }) | Each hook takes controlled-query options (query, attributes, autoExecute) and calls method(query, attributes, abortController). |
methodNameToHookName(name) | Prefixes use and uppercases the first character; empty name throws. |
collectMethods(obj) | Returns a Map of bound methods: own and prototype-chain function properties, nearest wins. Skips constructor, Object.prototype and accessors, so collecting never runs a getter. |
Execute hooks pass the controller only when a hook sets appendAbortController: true: the method is then called as method(...params, abortController), and a @api method picks the controller up wherever it lands, so replacing, aborting or unmounting an execution cancels its request. Leave it off for methods with optional trailing parameters, where the controller would take a parameter's place; wrap such a method in your own service method instead. Query factories forward attributes and controller automatically. Both execute functions resolve to the final state and never reject.
APIHooks, QueryAPIHooks, UseApiMethodExecuteReturn, HookName, ApiHooksMapping, ApiMethod, QueryMethod, FunctionParameters, FunctionReturnType, IsPromiseFunction describe compile-time mappings. Runtime discovery checks whether a property is a function, not whether it really returns a Promise. Functions provided by getters are not turned into hooks. Only supply a trusted service object. Cancellation, callbacks, stale-result suppression and unmount rules are the shared executor contract.
Changed in 6.0
onBeforeExecute and the OnBeforeExecuteCallback type were removed; UseApiMethodExecuteOptions lost its first type parameter (TArgs). Query hooks take query from your state instead of initialQuery/setQuery/getQuery. collectMethods takes one argument, and getter-provided functions no longer become hooks.
Complete example
import { createExecuteApiHooks } from '@ahoo-wang/fetcher-react';
const hooks = createExecuteApiHooks({
api: {
async double(value: number) {
return value * 2;
},
},
});
export function Calculator() {
const { execute, result, error } = hooks.useDouble();
return (
<section>
<button
onClick={async () => {
const state = await execute(21);
if (state.status === 'success') console.log(state.result);
}}
>
Calculate
</button>
<output>{result}</output>
{error && <p role="alert">{error.message}</p>}
</section>
);
}Public signatures and types
These signatures follow declarations reachable from the current root entry. ? marks optional input; generics/interfaces only constrain compile-time types. Locate inherited and related types through the symbol index. Runtime defaults and failure behavior are described above.
methodNameToHookName
export function methodNameToHookName(methodName: string): string;packages/react/src/api/apiHooks.ts:15
collectMethods
export function collectMethods<T extends (...args: any[]) => Promise<any>>(
obj: object,
): Map<string, T>;packages/react/src/api/apiHooks.ts:28
CreateApiHooksOptions
export interface CreateApiHooksOptions<API extends Record<string, any>> {
api: API;
}packages/react/src/api/apiHooks.ts:50
HookName
export type HookName<K extends string> = `use${Capitalize<K>}`;packages/react/src/api/apiHooks.ts:54
IsPromiseFunction
export type IsPromiseFunction<T> = T extends (...args: any[]) => Promise<any>
? true
: false;packages/react/src/api/apiHooks.ts:56
FunctionParameters
export type FunctionParameters<T> = T extends (...args: infer P) => Promise<any>
? P
: never;packages/react/src/api/apiHooks.ts:60
FunctionReturnType
export type FunctionReturnType<T> = T extends (
...args: any[]
) => Promise<infer R>
? Awaited<R>
: never;packages/react/src/api/apiHooks.ts:64
ApiMethod
export type ApiMethod<TArgs extends any[] = any[], TReturn = any> = (
...args: TArgs
) => Promise<TReturn>;packages/react/src/api/apiHooks.ts:70
QueryMethod
export type QueryMethod<Q = any, TReturn = any> = (
query: Q,
attributes?: Record<string, any>,
abortController?: AbortController,
) => Promise<TReturn>;packages/react/src/api/apiHooks.ts:75
ApiHooksMapping
export type ApiHooksMapping<
API extends Record<string, any>,
MethodType extends (...args: any[]) => Promise<any>,
HookType,
> = {
[
K in keyof API as API[K] extends MethodType ? HookName<string & K> : never
]: API[K] extends MethodType ? HookType : never;
};packages/react/src/api/apiHooks.ts:81
createExecuteApiHooks
export function createExecuteApiHooks<
API extends Record<string, any>,
E = FetcherError,
>(options: CreateExecuteApiHooksOptions<API>): APIHooks<API, E>;packages/react/src/api/createExecuteApiHooks.ts:100
CreateExecuteApiHooksOptions
export interface CreateExecuteApiHooksOptions<
API extends Record<string, any>,
> extends CreateApiHooksOptions<API> {}packages/react/src/api/createExecuteApiHooks.ts:31
UseApiMethodExecuteOptions
export interface UseApiMethodExecuteOptions<
TData = any,
E = FetcherError,
> extends UseExecutePromiseOptions<TData, E> {
/** @default false */
appendAbortController?: boolean;
}packages/react/src/api/createExecuteApiHooks.ts:35
UseApiMethodExecuteReturn
export type UseApiMethodExecuteReturn<
TArgs extends any[],
TData,
E = FetcherError,
> = Omit<UseExecutePromiseReturn<TData, E>, 'execute'> & {
execute: (...params: TArgs) => Promise<PromiseState<TData, E>>;
};packages/react/src/api/createExecuteApiHooks.ts:47
APIHooks
export type APIHooks<API extends Record<string, any>, E = FetcherError> = {
[
K in keyof API as API[K] extends ApiMethod ? HookName<string & K> : never
]: API[K] extends ApiMethod
? (
options?: UseApiMethodExecuteOptions<FunctionReturnType<API[K]>, E>,
) => UseApiMethodExecuteReturn<
FunctionParameters<API[K]>,
FunctionReturnType<API[K]>,
E
>
: never;
};packages/react/src/api/createExecuteApiHooks.ts:56
createQueryApiHooks
export function createQueryApiHooks<
API extends Record<string, any>,
E = FetcherError,
>(options: CreateQueryApiHooksOptions<API>): QueryAPIHooks<API, E>;packages/react/src/api/createQueryApiHooks.ts:69
CreateQueryApiHooksOptions
export interface CreateQueryApiHooksOptions<
API extends Record<string, any>,
> extends CreateApiHooksOptions<API> {}packages/react/src/api/createQueryApiHooks.ts:24
UseApiMethodQueryOptions
export interface UseApiMethodQueryOptions<
Q,
TData = any,
E = FetcherError,
> extends Omit<UseQueryOptions<Q, TData, E>, 'execute'> {
attributes?: Record<string, any>;
}packages/react/src/api/createQueryApiHooks.ts:28
QueryAPIHooks
export type QueryAPIHooks<API extends Record<string, any>, E = FetcherError> = {
[
K in keyof API as API[K] extends QueryMethod ? HookName<string & K> : never
]: API[K] extends QueryMethod<infer Q, infer R>
? (options?: UseApiMethodQueryOptions<Q, R, E>) => UseQueryReturn<R, E>
: never;
};packages/react/src/api/createQueryApiHooks.ts:37
Related topics
Fetcher hooks · Promise and query state · Debounced execution · Storage and event subscriptions · Security hooks and route guards · Latest and stable values
