import { useSelector, useDispatch } from 'react-redux'; import { useEffect, useMemo, useRef } from 'react'; import type { LoadingState } from 'robodux'; import type { QueryState } from './slice'; import { selectLoaderById, selectDataById } from './slice'; type ActionFn
= (p: P) => { toString: () => string }; type ActionFnSimple = () => { toString: () => string }; interface SagaAction
{ type: string; payload: { key: string; options: P }; } export interface UseApiProps
extends LoadingState { trigger: (p: P) => void; action: ActionFn
;
}
export interface UseApiSimpleProps extends LoadingState {
trigger: () => void;
action: ActionFn;
}
export interface UseApiAction
extends LoadingState {
trigger: () => void;
action: A;
}
export type UseApiResult =
| UseApiProps
| UseApiSimpleProps
| UseApiAction;
interface UseCacheResult >(
action: A,
): UseApiAction;
export function useApi >(
action: ActionFn ,
): UseApiProps(
action: SagaAction | ActionFn,
) {
const id = typeof action === 'function' ? `${action}` : action.payload.key;
return useSelector((s: S) => selectLoaderById(s, { id }));
}
/**
* useApi will take an action creator or action itself and fetch
* the associated loader and create a `trigger` function that you can call
* later in your react component.
*
* This hook will *not* fetch the data for you because it does not know how to fetch
* data from your redux state.
*
* @example
* ```ts
* import { useApi } from 'saga-query/react';
*
* import { api } from './api';
*
* const fetchUsers = api.get('/users', function*() {
* // ...
* });
*
* const View = () => {
* const { isLoading, trigger } = useApi(fetchUsers);
* useEffect(() => {
* trigger();
* }, []);
* return