1
1
import { useEvent , useMergedState } from 'rc-util' ;
2
+ import raf from 'rc-util/lib/raf' ;
2
3
import React from 'react' ;
3
4
4
- // We need wait for outside state updated.
5
- // Which means need 2 effect:
6
- // 1. Outside sync state
7
- // 2. Still may be old state
8
- // 3. Safe to sync state
9
- const DELAY_TIMES = 2 ;
10
-
11
5
/**
12
6
* Will be `true` immediately for next effect.
13
7
* But will be `false` for a delay of effect.
@@ -21,10 +15,14 @@ export default function useDelayState<T>(
21
15
value,
22
16
} ) ;
23
17
24
- const [ times , setTimes ] = React . useState < number | false > ( false ) ;
25
18
const nextValueRef = React . useRef < T > ( value ) ;
26
19
27
20
// ============================= Update =============================
21
+ const rafRef = React . useRef < number > ( ) ;
22
+ const cancelRaf = ( ) => {
23
+ raf . cancel ( rafRef . current ) ;
24
+ } ;
25
+
28
26
const doUpdate = useEvent ( ( ) => {
29
27
setState ( nextValueRef . current ) ;
30
28
@@ -34,24 +32,18 @@ export default function useDelayState<T>(
34
32
} ) ;
35
33
36
34
const updateValue = useEvent ( ( next : T , immediately ?: boolean ) => {
35
+ cancelRaf ( ) ;
36
+
37
37
nextValueRef . current = next ;
38
38
39
39
if ( next || immediately ) {
40
40
doUpdate ( ) ;
41
- setTimes ( false ) ;
42
41
} else {
43
- setTimes ( 0 ) ;
42
+ rafRef . current = raf ( doUpdate ) ;
44
43
}
45
44
} ) ;
46
45
47
- // ============================= Effect =============================
48
- React . useEffect ( ( ) => {
49
- if ( times === DELAY_TIMES ) {
50
- doUpdate ( ) ;
51
- } else if ( times !== false && times < DELAY_TIMES ) {
52
- setTimes ( times + 1 ) ;
53
- }
54
- } , [ times , doUpdate ] ) ;
46
+ React . useEffect ( ( ) => cancelRaf , [ ] ) ;
55
47
56
48
return [ state , updateValue ] ;
57
49
}
0 commit comments