Created
July 30, 2019 10:23
-
-
Save Cloudo/b09a01faf65966fdd8ccae9b55c57046 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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