diff --git a/package.json b/package.json index be8da40..7da1eb6 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ ] }, "dependencies": { - "lodash.debounce": "^4.0.8" + "lodash.debounce": "^4.0.8", + "ohmyfetch": "^0.4.18" } } diff --git a/src/index.tsx b/src/index.tsx index b964132..c4f6acc 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,10 @@ export { default as usePromiseState } from './usePromiseState'; -export * from './usePromiseState'; +export * from './usePromiseState/type'; + export { default as useShuttle } from './useShuttle'; + export { default as useTimeout } from './useTimeout'; -export * from './useTimeout'; +export * from './useTimeout/type'; + +export { default as useFetch } from './useFetch'; +export * from './useFetch/type'; diff --git a/src/useFetch/index.ts b/src/useFetch/index.ts new file mode 100644 index 0000000..1ea4d83 --- /dev/null +++ b/src/useFetch/index.ts @@ -0,0 +1,4 @@ +export * from './type'; +import useFetch from './use-fetch'; + +export default useFetch; \ No newline at end of file diff --git a/src/useFetch/type.ts b/src/useFetch/type.ts new file mode 100644 index 0000000..ce6a3d5 --- /dev/null +++ b/src/useFetch/type.ts @@ -0,0 +1,16 @@ +import { SearchParams } from 'ohmyfetch'; + +export type UseFetchOptions = { + method?: string; + params?: SearchParams; + body?: RequestInit['body'] | Record; + headers?: { key: string; value: string }[]; + baseURL?: string; +}; + +export type UseFetch = { + data: DataT | null; + pending: boolean; + refresh: (() => Promise) | undefined; + error: Error | boolean; +}; \ No newline at end of file diff --git a/src/useFetch/use-fetch.ts b/src/useFetch/use-fetch.ts new file mode 100644 index 0000000..4de2da0 --- /dev/null +++ b/src/useFetch/use-fetch.ts @@ -0,0 +1,40 @@ +import { useEffect, useState } from 'react'; +import { $fetch } from 'ohmyfetch'; +import { UseFetchOptions, UseFetch } from './type'; + +/** + * This hook is a react mimic implementation for useLazyFetch in Nuxt3 + * https://v3.nuxtjs.org/api/composables/use-lazy-fetch + * + * This hook provides a convenient wrapper for $fetch + * @param url fetch url + * @param options options for method, params, body, headers and baseURL, check [ohmyfetch](https://github.com/unjs/ohmyfetch) for more. + * @returns { data, pending, refresh, error } + */ +export default function useFetch( + url: string | undefined | null | false, + options?: UseFetchOptions +): UseFetch { + const [data, setData] = useState(null); + const [pending, setPending] = useState(false); + const [error, setError] = useState(false); + + async function fetch() { + if (!url) throw new Error('Missing URL'); + try { + setError(false); + setPending(true); + const result = await $fetch(url, options); + setData(result); + } catch (e) { + setError(e as Error); + } finally { + setPending(false); + } + } + + useEffect(() => { + if (url) fetch(); + }, [url, options]); + return { data, pending, refresh: url ? fetch : undefined, error }; +} diff --git a/yarn.lock b/yarn.lock index dac2a58..a3a90e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2640,6 +2640,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +destr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/destr/-/destr-1.1.1.tgz#910457d10a2f2f247add4ca4fdb4a03adcc49079" + integrity sha512-QqkneF8LrYmwATMdnuD2MLI3GHQIcBnG6qFC2q9bSH430VTCDAVjcspPmUaKhPGtAtPAftIUFqY1obQYQuwmbg== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -5230,6 +5235,11 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-fetch-native@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-0.1.4.tgz#09b06754f9e298bac23848050da2352125634f89" + integrity sha512-10EKpOCQPXwZVFh3U1ptOMWBgKTbsN7Vvo6WVKt5pw4hp8zbv6ZVBZPlXw+5M6Tyi1oc1iD4/sNPd71KYA16tQ== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -5380,6 +5390,16 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +ohmyfetch@^0.4.18: + version "0.4.18" + resolved "https://registry.yarnpkg.com/ohmyfetch/-/ohmyfetch-0.4.18.tgz#2952e04bd52662d0618d3d2f344db0250c3eeac2" + integrity sha512-MslzNrQzBLtZHmiZBI8QMOcMpdNFlK61OJ34nFNFynZ4v+4BonfCQ7VIN4EGXvGGq5zhDzgdJoY3o9S1l2T7KQ== + dependencies: + destr "^1.1.1" + node-fetch-native "^0.1.3" + ufo "^0.8.4" + undici "^5.2.0" + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -6931,6 +6951,11 @@ typescript@^4.7.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +ufo@^0.8.4: + version "0.8.5" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.8.5.tgz#e367b4205ece9d9723f2fa54f887d43ed1bce5d0" + integrity sha512-e4+UtA5IRO+ha6hYklwj6r7BjiGMxS0O+UaSg9HbaTefg4kMkzj4tXzEBajRR+wkxf+golgAWKzLbytCUDMJAA== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -6941,6 +6966,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici@^5.2.0: + version "5.8.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.8.1.tgz#511d43ff6be02f84ec2513ae7f4b07c589319272" + integrity sha512-iDRmWX4Zar/4A/t+1LrKQRm102zw2l9Wgat3LtTlTn8ykvMZmAmpq9tjyHEigx18FsY7IfATvyN3xSw9BDz0eA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"