diff --git a/.eslintrc.js b/.eslintrc.js index ae5bc658e5020bc3c168172de2412f92cd9c5a32..4c0c2c768013e91386c543796b94bfe05a4f4429 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,4 +11,8 @@ module.exports = { env: { browser: true, }, + + rules: { + 'implicit-arrow-linebreak': 0, + }, }; diff --git a/src/hooks/types.ts b/src/hooks/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..4eafda4a634214a954938d97ebafbfeb230a8e3f --- /dev/null +++ b/src/hooks/types.ts @@ -0,0 +1,28 @@ +import { AxiosPromise } from 'axios'; + +export interface ResponseData<T> { + isLoading: boolean; + isError: boolean; + data?: T; +} + +export interface RequestArgs<T = any> { + request: ApiRequest<T>; + initialData?: T; + initialParams?: RequestParams; +} + +export interface RequestParams { + body?: any; + params?: any; + args?: any; +} +export type ApiRequest<T> = (params: RequestParams) => AxiosPromise<T>; + +export type Refetch = (params?: RequestParams) => void; + +export interface INews { + title: string; + text: string; + publishedAt: string; +} diff --git a/src/hooks/useRequest.ts b/src/hooks/useRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..04963c44cb754f94d83b6ade0496ceb55260e6e5 --- /dev/null +++ b/src/hooks/useRequest.ts @@ -0,0 +1,44 @@ +import { useCallback, useEffect, useState } from 'react'; +import { Refetch, RequestArgs, ResponseData } from './types'; + +function useRequest<T = any>({ + request, + initialData, + initialParams, +}: RequestArgs<T>): [ResponseData<T>, Refetch] { + const [data, setData] = useState(initialData); + const [isLoading, setIsLoading] = useState(false); + const [isError, setIsError] = useState(false); + const [fetching, setFetching] = useState(false); + const [requestParams, setRequestParams] = useState(initialParams ?? {}); + + const refetch = useCallback((newParams?) => { + setRequestParams(newParams ?? {}); + setFetching(true); + }, []); + + useEffect(() => { + const fetchData = async () => { + setIsError(false); + setIsLoading(true); + + try { + const result = await request(requestParams); + + setData(result.data); + } catch (error) { + setIsError(true); + } + setFetching(false); + setIsLoading(false); + }; + + if (fetching && !isLoading) { + fetchData(); + } + }, [request, fetching, isLoading, requestParams]); + + return [{ data, isLoading, isError }, refetch]; +} + +export default useRequest;