UNPKG

@mdus/use-http-request-hook

Version:

A production-ready React hook for making HTTP requests with built-in GET caching, debounce support, waterfall protection, and AbortController cancellation.

2 lines (1 loc) 1.57 kB
import{useState as e,useRef as t,useMemo as r,useCallback as n,useEffect as o}from"react";const c=new Map,a=new Map;function u(){c.clear(),a.clear()}function s(e){c.delete(e),a.delete(e)}function l(u,s={}){const[l,d]=e(null),[i,h]=e(null),[f,b]=e(!0),y=t(null),m=t(null),p=t(!1),T=r(()=>({method:s.method||"GET",headers:s.headers||{},body:s.body||null,debounce:s.debounce||0}),[s.method,s.headers,s.body,s.debounce]),g=n(()=>{if(!u)return;const e=T.method.toUpperCase(),t={...T.headers},r="GET"!==e&&T.body?JSON.stringify(T.body):void 0;r&&!t["Content-Type"]&&(t["Content-Type"]="application/json");const n="GET"===e;if(n&&c.has(u))return d(c.get(u)),b(!1),void h(null);if(n&&a.has(u))return b(!0),void a.get(u).then(e=>{d(e),h(null)}).catch(e=>{"AbortError"!==e.name&&h(e.message)}).finally(()=>b(!1));y.current=new AbortController;const{signal:o}=y.current,s=async()=>{b(!0),h(null);const s=fetch(u,{method:e,headers:t,body:r,signal:o}).then(async e=>{if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return e.json()}).then(e=>{if(n&&e){if(c.size>=100){const e=c.keys().next().value;c.delete(e)}c.set(u,e)}return e});n&&(a.set(u,s),p.current=!0);try{const e=await s;d(e)}catch(e){"AbortError"!==e.name&&h(e.message)}finally{b(!1),n&&a.delete(u)}};m.current&&clearTimeout(m.current),T.debounce>0?m.current=setTimeout(s,T.debounce):s()},[u,T]);return o(()=>(g(),()=>{y.current&&y.current.abort(),m.current&&clearTimeout(m.current),p.current&&a.delete(u)}),[g]),{data:l,error:i,isLoading:f,refetch:g}}export{u as clearCache,l as default,s as invalidateURL};