summaryrefslogtreecommitdiff
path: root/packages/anastasis-webui/src/hooks/async.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-webui/src/hooks/async.ts')
-rw-r--r--packages/anastasis-webui/src/hooks/async.ts21
1 files changed, 20 insertions, 1 deletions
diff --git a/packages/anastasis-webui/src/hooks/async.ts b/packages/anastasis-webui/src/hooks/async.ts
index 0fc197554..5235e1e3e 100644
--- a/packages/anastasis-webui/src/hooks/async.ts
+++ b/packages/anastasis-webui/src/hooks/async.ts
@@ -18,7 +18,7 @@
*
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { useState } from "preact/hooks";
+import { useCallback, useEffect, useRef, useState } from "preact/hooks";
// import { cancelPendingRequest } from "./backend";
export interface Options {
@@ -34,6 +34,17 @@ export interface AsyncOperationApi<T> {
error: string | undefined;
}
+export function useIsMounted() {
+ const isMountedRef = useRef(true);
+ const isMounted = useCallback(() => isMountedRef.current, []);
+
+ useEffect(() => {
+ return () => void (isMountedRef.current = false);
+ }, []);
+
+ return isMounted;
+}
+
export function useAsync<T>(
fn?: (...args: any) => Promise<T>,
{ slowTolerance: tooLong }: Options = { slowTolerance: 1000 },
@@ -42,11 +53,15 @@ export function useAsync<T>(
const [isLoading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<any>(undefined);
const [isSlow, setSlow] = useState(false);
+ const isMounted = useIsMounted();
const request = async (...args: any) => {
if (!fn) return;
setLoading(true);
const handler = setTimeout(() => {
+ if (!isMounted()) {
+ return;
+ }
setSlow(true);
}, tooLong);
@@ -54,6 +69,10 @@ export function useAsync<T>(
console.log("calling async", args);
const result = await fn(...args);
console.log("async back", result);
+ if (!isMounted()) {
+ // Possibly calling fn(...) resulted in the component being unmounted.
+ return;
+ }
setData(result);
} catch (error) {
setError(error);