mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1ntr8jjcqq6gt06q5avvqttfjgpwshmra22pcmcagdnukw4ja4nqqsa9g54 <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@sprout-oss.stage.blox.sqprod.co>
58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
|
export interface Resource<T> {
|
|
data?: T;
|
|
error?: Error;
|
|
loading: boolean;
|
|
stale: boolean;
|
|
refetch: () => void;
|
|
}
|
|
|
|
export function useResource<T>(
|
|
load: () => Promise<T>,
|
|
key: string,
|
|
): Resource<T> {
|
|
const [data, setData] = useState<T>();
|
|
const [error, setError] = useState<Error>();
|
|
const [loading, setLoading] = useState(true);
|
|
const [revision, setRevision] = useState(0);
|
|
const loadRef = useRef(load);
|
|
const activeRequest = useRef("");
|
|
loadRef.current = load;
|
|
const refetch = useCallback(() => setRevision((value) => value + 1), []);
|
|
|
|
useEffect(() => {
|
|
const requestId = `${key}\0${revision}`;
|
|
activeRequest.current = requestId;
|
|
const isCurrent = () => activeRequest.current === requestId;
|
|
const loadCurrent = async () => {
|
|
setLoading(true);
|
|
setError(undefined);
|
|
try {
|
|
const value = await loadRef.current();
|
|
if (isCurrent()) setData(value);
|
|
} catch (reason) {
|
|
if (isCurrent()) {
|
|
setError(
|
|
reason instanceof Error ? reason : new Error("Request failed"),
|
|
);
|
|
}
|
|
} finally {
|
|
if (isCurrent()) setLoading(false);
|
|
}
|
|
};
|
|
void loadCurrent();
|
|
return () => {
|
|
activeRequest.current = "";
|
|
};
|
|
}, [key, revision]);
|
|
|
|
return {
|
|
data,
|
|
error,
|
|
loading,
|
|
stale: loading && data !== undefined,
|
|
refetch,
|
|
};
|
|
}
|