Skip to content

Instantly share code, notes, and snippets.

@rtatarinov4xxi
Last active August 26, 2023 03:51
Show Gist options
  • Save rtatarinov4xxi/5376973474588d1744c91a12d2db6185 to your computer and use it in GitHub Desktop.
Save rtatarinov4xxi/5376973474588d1744c91a12d2db6185 to your computer and use it in GitHub Desktop.
useRequest hook with Axios by typescript (with examples)
import { useState } from 'react';
import axios from 'axios';
type RequestConfig = {
url?: string;
baseURL?: string;
initialIsLoading?: boolean;
withCredentials?: boolean;
onSuccess?: Function;
onError?: Function;
method?: any;
data?: any;
};
type ResponseState = {
data: any;
isLoading: boolean | undefined;
error: object | null;
settings: object;
};
type RequestFunction = any;
type RequestResult = [ResponseState, RequestFunction];
const BASE_API_URL = 'htttp://localhost/api'
const defaultConfig: RequestConfig = {
url: '',
method: 'get',
initialIsLoading: false,
withCredentials: true,
baseURL: BASE_API_URL,
onSuccess: Function.prototype,
onError: Function.prototype,
};
export const useRequest = (config: Readonly<RequestConfig>): RequestResult => {
const settings = { ...defaultConfig, ...config };
const {
url,
method,
baseURL,
initialIsLoading,
onSuccess,
onError,
withCredentials,
} = settings;
const [isLoading, setIsLoading] = useState<boolean | undefined>(
initialIsLoading,
);
const [error, setError] = useState<object | null>(null);
const [data, setData] = useState<object | null>(null);
const handleSuccessRequest = (serverData: any): void => {
setIsLoading(false);
if (serverData) {
setError(null);
setData(serverData);
if (onSuccess) {
onSuccess(serverData);
}
}
};
const handleErrorRequest = (serverError: object): void => {
setIsLoading(false);
if (serverError) {
setError(serverError);
if (onError) {
onError(serverError);
}
}
};
const request = async (payload: any, options: object): Promise<any> => {
try {
setIsLoading(true);
let requestConfig: RequestConfig = {
baseURL,
withCredentials,
url,
method,
};
if (payload) {
requestConfig = { ...requestConfig, data: payload };
}
if (options) {
requestConfig = { ...requestConfig, ...options };
}
const { data: serverData } = await axios(requestConfig);
handleSuccessRequest(serverData);
} catch (error) {
if (axios.isCancel(error)) {
console.error('Request canceled by axios', error.message);
} else {
handleErrorRequest(error);
}
}
};
const state: ResponseState = { data, isLoading, error, settings };
return [state, request];
};
// --- Usage examples ---
// [GET]
import React, { useState, useEffect } from 'react';
type Props = {
id: string;
}
const SomeComponent = ({ id }: Props): JSX.Element => {
const [state, getSomething] = useRequest({
url: `/something/${id}`,
initialIsLoading: true,
});
const { isLoading, data, error, settings } = state;
useEffect(() => {
console.log('Function will call with next settings: ' settings);
getSomething();
}, [])
return (
<>
{isLoading && <p>Loading ...</p>}
{error && <p>Error</p>}
{data && <div>{data.html}<div/>}
</>
);
};
// [POST]
import React, { useState, useEffect } from 'react';
const SomeComponent = (): JSX.Element => {
const [isCreated, setIsCreated] = useState<boolean>(false);
const [state, createSomething] = useRequest({
method: 'post',
url: `/something/create`,
onSuccess: () => { setIsCreated(true); }
});
const { isLoading, error } = state;
const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
const payload = { value: 'somethingNewValue' };
createSomething(payload);
}
rreturn (
<>
{isCreated ? (
<p>Success!</p>
) : (
<>
<button onClick={handleClick} disabled={isLoading}>
Some button
</button>
{error && <p>Error</p>}
</>
)}
</>
);
};
// [PATCH]
import React, { useState, useEffect } from 'react';
const SomeComponent = (): JSX.Element => {
const [state, patchSomething] = useRequest({
method: 'patch',
});
const { isLoading, error } = state;
const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
const id = (e.target as HTMLElement).dataset.id;
const payload = { value: 'somethingNewValue' };
const requestOptions = {
url: `/something/${id}`
};
patchSomething(payload, requestOptions);
}
return (
<>
<button
data-id="something-button-id"
onClick={handleClick}
disabled={isLoading}
>
Some button
</button>
{error && <p>Error</p>}
</>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment