Skip to content

Instantly share code, notes, and snippets.

@Cloudo
Created July 30, 2019 10:23
Show Gist options
  • Save Cloudo/b09a01faf65966fdd8ccae9b55c57046 to your computer and use it in GitHub Desktop.
Save Cloudo/b09a01faf65966fdd8ccae9b55c57046 to your computer and use it in GitHub Desktop.
import { useEffect, useRef } from 'react'
import { isEqual } from 'lodash'
import { notice } from 'uikit'
import { handleFetchError } from 'utils/exceptions'
import { useSafeSetState } from './useSetState'
function usePrevious(value) {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
function useDeepCompareEffect(callback, inputs) {
const cleanupRef = useRef()
useEffect(() => {
if (!isEqual(previousInputs, inputs)) {
cleanupRef.current = callback()
}
return cleanupRef.current
})
const previousInputs = usePrevious(inputs)
}
function useRequest({
api,
args,
prepareArgs = args => args,
when = () => true,
transform = data => data,
defaultResponse = null,
errorMessage = 'Произошла ошибка получения данных формы',
autoFetch = true,
onSuccess,
}) {
const [state, setState] = useSafeSetState({
loaded: false,
fetching: false,
response: defaultResponse,
error: null,
requestId: 0,
})
const requestFn = async payload => {
if (!when(args)) return
const currentRequestId = state.requestId + 1
setState({ fetching: true, requestId: currentRequestId })
try {
const preparedArgs = prepareArgs(args)
const res = await api(preparedArgs, payload)
const response = transform(res)
setState({
response,
error: null,
loaded: true,
fetching: false,
})
if (onSuccess) {
onSuccess({ response, args: preparedArgs, payload })
}
} catch (error) {
// skip previous (cancelled) requests
if (state.requestId === currentRequestId) {
setState({
error,
response: defaultResponse,
loaded: false,
fetching: false,
})
handleFetchError(error, () => notice.error(errorMessage))
}
}
}
if (autoFetch) {
useDeepCompareEffect(
() => {
requestFn()
},
[args]
)
}
return {
...state,
fetch: requestFn,
}
}
export default useRequest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment