Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / hooks / useAsync.js
blob73973dcebd73362c67bd961bb48bf35aef80185b
1 import { useCallback, useReducer, useRef } from 'react';
3 import useIsMounted from '@proton/hooks/useIsMounted';
5 const DEFAULT_STATE = {
6     loading: false,
7 };
9 const reducer = (state, action) => {
10     switch (action.type) {
11         case 'loading':
12             return {
13                 ...state,
14                 loading: true,
15             };
16         case 'success':
17             return {
18                 error: undefined,
19                 loading: false,
20                 result: action.payload,
21             };
22         default:
23         case 'error':
24             return {
25                 result: undefined,
26                 loading: false,
27                 error: action.payload,
28             };
29     }
32 const useAsync = (setResults = true) => {
33     const [{ loading, result, error }, dispatch] = useReducer(reducer, DEFAULT_STATE);
34     const isMounted = useIsMounted();
35     const promiseRef = useRef();
37     const run = useCallback(async (promise) => {
38         const isCurrentPromise = () => promiseRef.current === promise;
39         promiseRef.current = promise;
41         dispatch({ type: 'loading' });
42         try {
43             const data = await promise;
44             if (isMounted() && isCurrentPromise()) {
45                 dispatch({ type: 'success', payload: setResults ? data : undefined });
46             }
47             return data;
48         } catch (e) {
49             if (isMounted() && isCurrentPromise() && e.name !== 'AbortError') {
50                 dispatch({ type: 'error', payload: setResults ? e : undefined });
51             }
52             throw e;
53         }
54     }, []);
56     return {
57         result,
58         error,
59         loading,
60         run,
61     };
64 export default useAsync;