@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
111 lines (99 loc) • 3.02 kB
text/typescript
import { useRef } from "react";
import { useDidUpdate } from "@better-hooks/lifecycle";
import { getRequestDispatcher, RequestInstance, Request, getRequestKey } from "@hyper-fetch/core";
import { UseCacheOptionsType, useCacheDefaultOptions, UseCacheReturnType } from "hooks/use-cache";
import { useRequestEvents, useTrackedState } from "helpers";
import { useConfigProvider } from "config-provider";
export const useCache = <T extends RequestInstance>(
request: T,
options: UseCacheOptionsType<T> = useCacheDefaultOptions,
): UseCacheReturnType<T> => {
const { cacheKey, client } = request;
const { cache, loggerManager } = client;
const logger = useRef(loggerManager.init("useCache")).current;
const [dispatcher] = getRequestDispatcher(request);
const updateKey = JSON.stringify(request.toJSON());
// Build the configuration options
const [globalConfig] = useConfigProvider();
const { dependencyTracking, initialData, deepCompare } = {
...useCacheDefaultOptions,
...globalConfig.useCacheConfig,
...options,
};
/**
* State handler with optimization for rerendering, that hooks into the cache state and dispatchers queues
*/
const [state, actions, { setRenderKey, setCacheData, getIsDataProcessing }] = useTrackedState<T>({
logger,
request,
dispatcher,
initialData,
deepCompare,
dependencyTracking,
});
/**
* Handles the data exchange with the core logic - responses, loading, downloading etc
*/
const [callbacks, listeners] = useRequestEvents({
logger,
actions,
request,
dispatcher,
setCacheData,
getIsDataProcessing,
});
const { addCacheDataListener, addLifecycleListeners } = listeners;
const handleMountEvents = () => {
addCacheDataListener(request);
addLifecycleListeners(request);
};
useDidUpdate(handleMountEvents, [updateKey], true);
const refetch = (invalidateKey?: string | RequestInstance | RegExp) => {
if (invalidateKey instanceof Request) {
cache.invalidate(getRequestKey(invalidateKey, true));
} else if (invalidateKey) {
cache.invalidate(invalidateKey);
} else {
cache.invalidate(cacheKey);
}
};
return {
get data() {
setRenderKey("data");
return state.data;
},
get error() {
setRenderKey("error");
return state.error;
},
get loading() {
setRenderKey("loading");
return state.loading;
},
get status() {
setRenderKey("status");
return state.status;
},
get success() {
setRenderKey("success");
return state.success;
},
get extra() {
setRenderKey("extra");
return state.extra;
},
get retries() {
setRenderKey("retries");
return state.retries;
},
get timestamp() {
setRenderKey("timestamp");
return state.timestamp;
},
onCacheError: callbacks.onError,
onCacheSuccess: callbacks.onSuccess,
onCacheChange: callbacks.onFinished,
...actions,
refetch,
};
};