Path: blob/master/src/packages/next/lib/hooks/api.ts
1453 views
import { useEffect, useRef, useState } from "react";1import apiPost from "lib/api/post";2import useIsMounted from "./mounted";3import { delay } from "awaiting";45interface Options {6endpoint: string;7params?: object;8cache_s?: number;9}1011export default function useAPI(12endpoint?: string,13params?: object,14cache_s?: number,15) {16const [counter, setCounter] = useState<number>(0);17const [error, setError] = useState<string>("");18const [result, setResult] = useState<any>(undefined);19const [calling, setCalling] = useState<boolean>(false);20const queue = useRef<Options[]>([]);21const isMounted = useIsMounted();2223async function call(24endpoint1: string | undefined = endpoint,25params1: object | undefined = params,26cache_s1: number | undefined = cache_s,27): Promise<any> {28if (endpoint1 == undefined) return;29if (calling) {30queue.current.push({31endpoint: endpoint1,32params: params1,33cache_s: cache_s1,34});35return;36}37setCalling(true);38let result;39try {40setError("");41result = await apiPost(endpoint1, params1, cache_s);42} catch (err) {43if (!isMounted.current) return;44setCalling(false);45setError(`${err}`);46setResult({ error: err });47queue.current = [];48return;49}50if (!isMounted.current) return;51setCalling(false);52setResult(result);53if (queue.current.length > 0) {54const next = queue.current.shift();55if (next == null) return;56const { endpoint, params, cache_s } = next;57if (!isMounted.current) return;58await delay(1);59call(endpoint, params, cache_s);60}61}6263useEffect(() => {64if (endpoint) {65call(endpoint, params, cache_s);66}67}, [counter, endpoint + JSON.stringify(params)]);6869return {70error,71result,72calling,73call,74refresh: () => {75setCounter(counter + 1);76},77};78}798081