dev: avoid double requests
Massimo Melina committed
Sep 12, 2023 at 22:57 UTC
51825a7edbe10b2196202a9638f45c75533e3166
1 file changed
+7
-5
shared/api.ts
+7
-5
@@ -2,7 +2,7 @@
2
3
import _ from 'lodash';
4
import { useCallback, useEffect, useRef } from 'react';
5
-import { Dict, Falsy, getPrefixUrl, pendingPromise, useStateMounted } from '.'
5
+import { Dict, Falsy, getPrefixUrl, pendingPromise, useStateMounted, wait } from '.'
6
7
export const API_URL = '/~/api/'
8
@@ -74,19 +74,21 @@ export function useApi<T=any>(cmd: string | Falsy, params?: object) {
74
const [forcer, setForcer] = useStateMounted(0)
75
const loadingRef = useRef<ReturnType<typeof apiCall>>()
76
const reloadingRef = useRef<any>()
77
- useEffect(()=>{
77
+ useEffect(() => {
78
loadingRef.current?.abort()
79
setData(undefined)
80
setError(undefined)
81
if (!cmd) return
82
let aborted = false
83
- const req = apiCall<T>(cmd, params)
84
- const wholePromise = req.then(x => aborted || setData(x), x => aborted || setError(x))
83
+ let req: undefined | ReturnType<typeof apiCall>
84
+ const wholePromise = wait(0) // postpone a bit, so that if it is aborted immediately, it is never really fired (happens mostly in dev mode)
85
+ .then(() => aborted ? undefined : req = apiCall<T>(cmd, params))
86
+ .then(res => aborted || setData(res), err => aborted || setError(err))
87
.finally(() => loadingRef.current = reloadingRef.current = undefined)
88
loadingRef.current = Object.assign(wholePromise, {
89
abort() {
90
aborted = true
89
- req.abort()
91
+ req?.abort()
92
}
93
})
94
reloadingRef.current?.resolve(wholePromise)