Skip to content

Instantly share code, notes, and snippets.

@ynifamily3
Created March 25, 2021 09:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ynifamily3/f0fe0e740d64f75a6a5a584d9ed0c8dd to your computer and use it in GitHub Desktop.
Save ynifamily3/f0fe0e740d64f75a6a5a584d9ed0c8dd to your computer and use it in GitHub Desktop.
useAPI Hook
interface CombinedStatus<T> {
status: "IDLE" | "PENDING" | "SUCCESS" | "FAILURE";
data: T | null;
}
function useApi<ApiResultType extends object, Payload>(
repoFunc: (
payload: Payload
) => Promise<ApiResultType>
) {
const _repoFunc = useRef(repoFunc);
const _payload = useRef<Payload>({});
const [flag, setFlag] = useState(-1);
const [statusData, setStatusData] = useState<CombinedStatus<ApiResultType>>({
status: ApiStatus.IDLE,
data: null,
});
useEffect(() => {
let detached = false;
if (flag === -1) {
return;
}
setStatusData((statusData) => {
return { status: "PENDING", data: statusData.data };
});
_repoFunc
.current(_payload.current)
.then((d) => {
if (!detached) {
setStatusData({
status: "SUCCESS",
data: d,
});
}
})
.catch((error) => {
if (!detached) {
setStatusData({
status: "FAILURE",
data: null,
});
}
});
return () => {
detached = true;
};
}, [flag, _payload, _repoFunc]);
const call = useCallback((newPayload: Payload) => {
_payload.current = newPayload;
setFlag((r) => (r + 1) % 2);
}, []);
const status = statusData.status;
const data = statusData.data;
return { call, status, data };
}
export { useApi };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment