) => {
+ setFetchingState(true)
+ setError(null)
+ return promise
+ .catch((err) => {
+ setError(err)
+ return Promise.reject(err)
+ })
+ .finally(() => setFetchingState(false))
+ },
+ [],
+ )
+
+ return {
+ error,
+ isFetching,
+ switchState,
+ }
+}
+
+/**
+ * Хук для состояния загрузки.
+ * Получает asyncFunction функция возвращающая Promise
+ * и возвращает функцию обертку над asyncFunction
+ *
+ * Загрузка начинается при вызове обертки, заканчивается при завершении Promise
+ *
+ * ```ts
+ * const [countries, setCountries] = useState([])
+ *
+ * const { request: fetchCountries, isFetching } = useRequest(getCountries)
+ *
+ * useEffect(() => {
+ * fetchCountries().then(setCountries)
+ * }, [])
+ *
+ * return (
+ *
+ * {isFetching && 'Loading...'}
+ * ...
+ *
+ * )
+ * ```
+ */
+export const useRequest = <
+ F extends (...args: any) => Promise,
+>(asyncFunction: F) => {
+ const {
+ error,
+ isFetching,
+ switchState,
+ } = useRequestState()
+
+ const request = useCallback(
+ (...args: Parameters) => (
+ switchState(asyncFunction(...args)) as ReturnType
+ ),
+ [switchState, asyncFunction],
+ )
+
+ return {
+ error,
+ isFetching,
+ request,
+ }
+}