@hyper-fetch/react
Version:
React hooks and utils for the hyper-fetch
116 lines (104 loc) • 3.05 kB
text/typescript
import { useDidUpdate } from "@better-hooks/lifecycle";
import { getRequestDispatcher, RequestInstance } from "@hyper-fetch/core";
import { useRef } from "react";
import { UseCacheOptionsType, useCacheDefaultOptions, UseCacheReturnType } from "hooks/use-cache";
import { useRequestEvents, useTrackedState } from "helpers";
import { useProvider } from "provider";
export const useCache = <T extends RequestInstance>(
request: T,
options?: UseCacheOptionsType<T>,
): UseCacheReturnType<T> => {
const { cacheKey, client } = request;
const { cache, loggerManager } = client;
const logger = useRef(loggerManager.initialize(client, "useCache")).current;
const [dispatcher] = getRequestDispatcher(request);
const updateKey = JSON.stringify(request.toJSON());
// Build the configuration options
const { config: globalConfig } = useProvider();
const { dependencyTracking, initialResponse, 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,
initialResponse,
deepCompare,
dependencyTracking,
});
/**
* Handles the data exchange with the core logic - responses, loading, downloading etc
*/
const [, listeners] = useRequestEvents({
logger,
actions,
request,
dispatcher,
setCacheData,
getIsDataProcessing,
});
const { addCacheDataListener, addLifecycleListeners } = listeners;
const handleMountEvents = () => {
const unmountDataListener = addCacheDataListener(request);
const unmountLifecycleListener = addLifecycleListeners(request);
return () => {
unmountDataListener();
unmountLifecycleListener();
};
};
useDidUpdate(
() => {
return handleMountEvents();
},
[updateKey],
true,
);
const invalidate = (cacheKeys?: string | RegExp | RequestInstance | Array<string | RegExp | RequestInstance>) => {
cache.invalidate(cacheKeys ?? 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 responseTimestamp() {
setRenderKey("responseTimestamp");
return state.responseTimestamp;
},
get requestTimestamp() {
setRenderKey("requestTimestamp");
return state.requestTimestamp;
},
...actions,
invalidate,
};
};