import { useEffect } from "preact/hooks"; import { signal } from "@preact/signals"; export function useFetch( url: string, options?: FetchOptions, ): { data: T | null; loading: boolean; error: Error | null; refetch: (newURL?: string, newOptions?: FetchOptions) => void; } { const data = signal(null); const loading = signal(true); const error = signal(null); useEffect(() => { fetch(url, options) .then((response) => { if (!response.ok) { throw new Error("Failed to fetch data"); } return response.json(); }) .then((resp) => (data.value = resp)) .catch((err) => (error.value = err)) .finally(() => (loading.value = false)); }, [url, options]); const refetch = (newURL?: string, newOptions?: FetchOptions) => { loading.value = true; error.value = null; fetch(newURL || url, newOptions || options) .then((response) => { if (!response.ok) { throw new Error("Failed to fetch data"); } return response.json(); }) .then((resp) => (data.value = resp)) .catch((err) => (error.value = err)) .finally(() => (loading.value = false)); }; return { data: data.value, loading: loading.value, error: error.value, refetch, }; } export interface FetchOptions { method: "GET" | "POST" | "PUT" | "DELETE"; headers: Record; body: string; }