forked from Nova-reward/Nova-Rewards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseAsync.js
More file actions
38 lines (34 loc) · 1.03 KB
/
Copy pathuseAsync.js
File metadata and controls
38 lines (34 loc) · 1.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { useState, useCallback, useRef } from 'react';
/**
* Wraps an async function with loading / error / data state.
*
* @template T
* @param {(...args: any[]) => Promise<T>} asyncFn
* @returns {{ execute: (...args: any[]) => Promise<T|undefined>, data: T|null, loading: boolean, error: string|null, reset: () => void }}
*/
export function useAsync(asyncFn) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fnRef = useRef(asyncFn);
fnRef.current = asyncFn;
const execute = useCallback(async (...args) => {
setLoading(true);
setError(null);
try {
const result = await fnRef.current(...args);
setData(result);
return result;
} catch (err) {
setError(err?.message || 'An error occurred');
} finally {
setLoading(false);
}
}, []);
const reset = useCallback(() => {
setData(null);
setError(null);
setLoading(false);
}, []);
return { execute, data, loading, error, reset };
}