UNPKG

@hyper-fetch/react

Version:

React hooks and utils for the hyper-fetch

111 lines (99 loc) 3.02 kB
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, }; };