-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseStateWithPromise.ts
42 lines (37 loc) · 1 KB
/
useStateWithPromise.ts
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
39
40
41
42
import {
useState,
useRef,
useEffect,
useCallback,
Dispatch,
SetStateAction,
} from 'react'
export function useStateWithPromise<S = undefined>(
initialState: any
): [S | undefined, Dispatch<SetStateAction<S | undefined>>] {
const [state, setState] = useState(initialState)
const resolverRef = useRef(null)
useEffect(() => {
if (resolverRef.current) {
resolverRef.current(state)
resolverRef.current = null
}
/**
* Since a state update could be triggered with the exact same state again,
* it's not enough to specify state as the only dependency of this useEffect.
* That's why resolverRef.current is also a dependency, because it will guarantee,
* that handleSetState was called in previous render
*/
}, [resolverRef.current, state])
const handleSetState = useCallback(
(stateAction) => {
setState(stateAction)
return new Promise((resolve) => {
resolverRef.current = resolve
})
},
[setState]
)
return [state, handleSetState]
}
export default useStateWithPromise