Skip to content

Instantly share code, notes, and snippets.

@sina-byn
Last active September 25, 2022 09:31
Show Gist options
  • Save sina-byn/0fa01daf1a8351566f0822eca9c39343 to your computer and use it in GitHub Desktop.
Save sina-byn/0fa01daf1a8351566f0822eca9c39343 to your computer and use it in GitHub Desktop.
A react custom hook used to perfrom GET requests using axios - capable of handling both single GET requests and simultaneous GET requests + other options
import axios from 'axios';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
// types
type Entries = Entry[];
type Setter = Dispatch<SetStateAction<object>>;
type Params = { [key: string]: any };
interface Entry {
key: string;
url: string;
params?: Params;
}
interface Options {
setter: Setter;
params?: Params;
dependencies?: any[];
ssr?: boolean;
revalidation?: Revalidation;
}
interface Revalidation {
revalidate: boolean;
interval?: number;
}
const useAxios = () => ({
// handles single GET requests
get: (url: string, options: Options) => {
const { setter, params = {}, dependencies = [], ssr = false } = options;
const { revalidation = { revalidate: false, interval: 0 } } = options;
const { revalidate, interval = 15 * 1000 } = revalidation;
const [error, setError] = useState<Error>();
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
if (
url.includes('undefined') ||
Object.values(params).includes(undefined)
)
return;
setLoading(false);
// fetcher function
const fetcher = () => {
axios
.get(url.trim(), { params: params })
.then(({ data }) => setter(data))
.then(() => setLoading(false))
.catch(err => setError(err));
};
if (!ssr) fetcher();
let revalidator: NodeJS.Timer;
if (revalidate) {
revalidator = setInterval(fetcher, interval);
}
// cleanup function
return () => clearInterval(revalidator);
}, dependencies);
return { loading, error };
},
// handles single GET requests
get_all: (entries: Entries, options: Options) => {
const { setter, dependencies = [] } = options;
const { revalidation = { revalidate: false, interval: 0 } } = options;
const { revalidate, interval = 15 * 1000 } = revalidation;
const [error, setError] = useState<Error>();
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
if (dependencies.includes(undefined)) return;
setLoading(true);
// fetcher function and fetched object
const fetched: { [key: string]: any } = {};
const fetcher = () => {
axios
.all(
entries.map(entry => {
const { url, params = {} } = entry;
return axios.get(url.trim(), { params: params });
})
)
.then(
axios.spread((...all) => {
all.forEach(({ data }, idx) => {
const { key } = entries[idx];
fetched[key] = data;
});
setter(fetched);
setLoading(false);
})
)
.catch(err => setError(err));
};
fetcher();
let revalidator: NodeJS.Timer;
if (revalidate) {
revalidator = setInterval(fetcher, interval);
}
// cleanup function
return () => clearInterval(revalidator);
}, dependencies);
return { loading, error };
},
});
export default useAxios;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment