Skip to content

Instantly share code, notes, and snippets.

@kiishi
Last active September 18, 2022 22:57
Show Gist options
  • Save kiishi/68a7d9490d976bec07847a0b0615984f to your computer and use it in GitHub Desktop.
Save kiishi/68a7d9490d976bec07847a0b0615984f to your computer and use it in GitHub Desktop.
react-query like Http Hooks ( with some little extras )
import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { useEffect, useState } from 'react';
interface IRequestHookConfig {
// request params
params?: any;
// guards are like middlewares that run when a response is returned, before the state changes
// multiple guards can be added for different kind of checks
guards?: Array<(response: any, err: AxiosError | null) => Promise<void>>;
}
export const useGetHook = <T extends unknown = any>(
instance: AxiosInstance,
url: string,
config?: IRequestHookConfig
) => {
const [loading, setLoading] = useState(true);
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<AxiosError | null>(null);
const fetch = async () => {
setLoading(true);
try {
const response = await instance.get<T>(url, { params: config?.params });
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(response, null)));
}
setData(response.data);
} catch (err) {
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(null, err)));
}
setError(err);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetch();
return () => {
setError(null);
setData(null);
};
}, [config?.params]);
return { loading, data, error, refetch: fetch };
};
export const usePostHook = <T extends unknown = any>(
instance: AxiosInstance,
url: string,
config?: IRequestHookConfig
) => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<any>(null);
const makeRequest = async (body: any): Promise<AxiosResponse<T>> => {
setLoading(true);
try {
const response = await instance.post<T>(url, body, { params: config?.params ?? {} });
// run guards
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(response, null)));
}
setData(response.data);
setLoading(false);
return response;
} catch (error) {
// run guards
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(null, error)));
}
setError(error);
setLoading(false);
throw error;
}
};
return { loading, data, error, makeRequest };
};
export const useFormDataPostHook = <T extends unknown>(
instance: AxiosInstance,
url: string,
config?: IRequestHookConfig
) => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<any>(null);
const makeRequest = async (body: FormData): Promise<AxiosResponse<T>> => {
setLoading(true);
try {
const response = await instance.post<T>(url, body, {
params: config?.params ?? {},
headers: { 'Content-Type': 'multipart/form-data' },
});
// run guards
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(response, null)));
}
setData(response.data);
setLoading(false);
return response;
} catch (error) {
// run guards
if (config?.guards && config.guards.length != 0) {
await Promise.all(config.guards.map(async (eachGuard) => eachGuard(null, error)));
}
setError(error);
setLoading(false);
throw error;
}
};
return { loading, data, error, makeRequest };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment