From ff25f30850752ede05def712f5f1dba0495e1215 Mon Sep 17 00:00:00 2001
From: Maxime Jacquemin <maxime.jacquemin@cea.fr>
Date: Tue, 14 Sep 2021 15:58:33 +0200
Subject: [PATCH] [dome] A new hook to handle Promises.

The new hook `usePromise` allows to handle Promises, forcing React to
redraw the component when the Promises returns.
---
 ivette/src/dome/renderer/dome.tsx | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/ivette/src/dome/renderer/dome.tsx b/ivette/src/dome/renderer/dome.tsx
index f09729d827c..2a8a68cc993 100644
--- a/ivette/src/dome/renderer/dome.tsx
+++ b/ivette/src/dome/renderer/dome.tsx
@@ -518,6 +518,27 @@ export function useUpdate(...events: Event<any>[]) {
   });
 }
 
+/**
+   Hook to re-render when a Promise returns.
+   The promise will be typically created by using `React.useMemo()`.
+   The hook returns three informations:
+   - result: the promise result if it succeeds, undefined otherwise;
+   - error: the promise error if it fails, undefined otherwise;
+   - loading: the promise status, true if the promise is still running.
+*/
+export function usePromise<T>(job: Promise<T>) {
+  const [result, setResult] = React.useState<T | undefined>();
+  const [error, setError] = React.useState<Error | undefined>();
+  const [loading, setLoading] = React.useState(true);
+  React.useEffect(() => {
+    let cancel = false;
+    const term = (a: any) => { if (!cancel) { setLoading(false); return a; } };
+    job.then(term(setResult), term(setError));
+    return () => { cancel = true; };
+  }, [job]);
+  return { result, error, loading };
+}
+
 // --------------------------------------------------------------------------
 // --- Timer Hooks
 // --------------------------------------------------------------------------
-- 
GitLab