1
- import { useState , useEffect , useCallback } from 'react' ;
1
+ import { useState , useEffect , useCallback , useMemo } from 'react' ;
2
2
3
- const cache = new Set ( ) ;
3
+ const usePromiseCache = new Map < FunctionReturningPromise , Map < string , any > > ( ) ;
4
4
5
5
// These typings are borrowed from @raycast /utils package
6
6
type PromiseType < P extends Promise < any > > = P extends Promise < infer T > ? T : never ;
7
7
type FunctionReturningPromise < T extends any [ ] = any [ ] > = ( ...args : T ) => Promise < any > ;
8
8
type PromiseReturnType < T extends FunctionReturningPromise > = PromiseType < ReturnType < T > > ;
9
9
10
+ type UsePromiseOptions = {
11
+ execute ?: boolean ;
12
+ } ;
13
+
10
14
// Thank you Copilot
11
15
export const usePromise = < T extends FunctionReturningPromise > (
12
16
promise : T ,
13
- deps : any [ ] = [ ]
17
+ deps : any [ ] = [ ] ,
18
+ { execute = true } : UsePromiseOptions = { }
14
19
) : {
15
20
data : PromiseReturnType < T > | undefined ;
16
21
error : Error | undefined ;
@@ -21,25 +26,40 @@ export const usePromise = <T extends FunctionReturningPromise>(
21
26
const [ error , setError ] = useState < Error > ( ) ;
22
27
const [ isValidating , setIsValidating ] = useState ( false ) ;
23
28
29
+ const cachedKey = useMemo ( ( ) => {
30
+ return deps . map ( ( dep ) => dep . toString ( ) ) . join ( '' ) ;
31
+ } , [ deps ] ) ;
32
+
24
33
const mutate = useCallback ( ( ) => {
34
+ const currentData = usePromiseCache . get ( promise ) ?. get ( cachedKey ) ;
35
+
36
+ if ( currentData ) {
37
+ setData ( currentData ) ;
38
+ }
39
+
25
40
setIsValidating ( true ) ;
26
41
promise ( )
27
42
. then ( ( data ) => {
28
43
setData ( data ) ;
29
44
setIsValidating ( false ) ;
45
+
46
+ if ( ! usePromiseCache . has ( promise ) ) {
47
+ usePromiseCache . set ( promise , new Map ( ) ) ;
48
+ }
49
+
50
+ usePromiseCache . get ( promise ) ?. set ( cachedKey , data ) ;
30
51
} )
31
52
. catch ( ( error ) => {
32
53
setError ( error ) ;
33
54
setIsValidating ( false ) ;
34
55
} ) ;
35
- } , [ promise ] ) ;
56
+ } , [ cachedKey , promise ] ) ;
36
57
37
58
useEffect ( ( ) => {
38
- if ( ! cache . has ( promise ) ) {
39
- cache . add ( promise ) ;
59
+ if ( execute ) {
40
60
mutate ( ) ;
41
61
}
42
- } , deps ) ;
62
+ } , [ execute , mutate ] ) ;
43
63
44
64
return {
45
65
data,
0 commit comments