Skip to content

Instantly share code, notes, and snippets.

@ashimon83
Last active February 24, 2023 08:22
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ashimon83/bbd6b588a3aba5191f21d05df71e5e3e to your computer and use it in GitHub Desktop.
Save ashimon83/bbd6b588a3aba5191f21d05df71e5e3e to your computer and use it in GitHub Desktop.
import { useCallback, useEffect, useMemo, useState } from 'react'
import axios, { AxiosError, AxiosResponse, Method } from 'axios'
interface Params {
[key: string]: any
}
interface Args<T> {
url?: string
params?: Params
body?: Params
method?: Method
onSuccess?: (data?: T) => void
onError?: (err: AxiosError) => void
}
interface PostRequest {
method?: Method
url?: string
params?: Params
body?: Params
headers?: Headers
}
type DoPost<T> = ({ url, params }: Args<T>) => Promise<void>
interface PostResponse<T> {
doPost: DoPost<T>
isLoading: boolean
}
export function usePost<T> ({
method = 'post',
url,
params,
headers
}: PostRequest): PostResponse<T> {
const methodInternal = useMemo(() => method, [method])
const urlInternal = useMemo(() => url, [url])
const paramsInternal = useMemo(() => params, [params])
const [isLoading, setLoading] = useState(false)
const doPost = useCallback<DoPost<T>>(
async <T>(args: Args<T>) => {
const reqUrl = args.url ?? urlInternal ?? ''
if (!reqUrl) {
return
}
if (!methodInternal) {
return
}
try {
setLoading(true)
const res: AxiosResponse<T> = await axios.request({
method: args?.method ?? methodInternal,
url: reqUrl,
data: args?.params ?? paramsInternal ?? undefined,
headers
})
args.onSuccess?.(res.data)
} catch (err) {
args.onError?.(err as AxiosError)
} finally {
setLoading(false)
}
},
[headers, methodInternal, paramsInternal, urlInternal]
)
const clear = useCallback(() => {
setLoading(false)
}, [])
useEffect(() => () => clear(), [clear])
return {
doPost,
isLoading
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment