import { useEffect, useState } from "react"; export type Loaded = | { state: "loading" } | { state: "error"; message: string } | { state: "ready"; data: T }; async function getJson(path: string): Promise { const res = await fetch(path); if (!res.ok) throw new Error(`${path} answered ${res.status}`); return (await res.json()) as T; } export function useLoaded(url: string): Loaded { const [value, setValue] = useState>({ state: "loading" }); useEffect(() => { let live = true; setValue({ state: "loading" }); getJson(url) .then((data) => live && setValue({ state: "ready", data })) .catch((e: Error) => live && setValue({ state: "error", message: e.message })); return () => { live = false; }; }, [url]); return value; }