Fetch
Fetch is a utility component that fetches data from a URL and renders its children with the data.
import { useState, useEffect } from "react";
interface FetchProps<T> {
url: string;
children: (data: T) => React.ReactNode;
fallback: React.ReactNode;
errorFallback: React.ReactNode;
}
export function Fetch<T>({
url,
children,
fallback,
errorFallback,
}: FetchProps<T>) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then(setData)
.catch(() => setError(true))
.finally(() => setLoading(false));
}, [url]);
if (loading) return <>{fallback}</>;
if (error) return <>{errorFallback}</>;
return <>{data && children(data)}</>;
}
Using Axios
import { useState, useEffect } from "react";
interface IAxiosFetchProps<T> {
url: string;
children: (data: T) => React.ReactNode;
fallback: React.ReactNode;
errorFallback: React.ReactNode;
}
export function AxiosFetch<T>({
url,
children,
fallback,
errorFallback,
}: IAxiosFetchProps<T>) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useEffect(() => {
axios
.get(url)
.then((response) => response.data)
.then(setData)
.catch(() => setError(true))
.finally(() => setLoading(false));
}, [url]);
if (loading) return <>{fallback}</>;
if (error) return <>{errorFallback}</>;
return <>{data && children(data)}</>;
}
Usage
<Fetch
url="/api/data"
fallback={<span>Loading...</span>}
errorFallback={<span>Error loading data</span>}
>
{(data) => <div>{JSON.stringify(data)}</div>}
</Fetch>
Usage with Axios
<AxiosFetch
url="/api/data"
fallback={<span>Loading...</span>}
errorFallback={<span>Error loading data</span>}
>
{(data) => <div>{JSON.stringify(data)}</div>}
</AxiosFetch>