11import { useEvent , useMergedState } from 'rc-util' ;
2+ import raf from 'rc-util/lib/raf' ;
23import React from 'react' ;
34
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-
115/**
126 * Will be `true` immediately for next effect.
137 * But will be `false` for a delay of effect.
@@ -21,10 +15,14 @@ export default function useDelayState<T>(
2115 value,
2216 } ) ;
2317
24- const [ times , setTimes ] = React . useState < number | false > ( false ) ;
2518 const nextValueRef = React . useRef < T > ( value ) ;
2619
2720 // ============================= Update =============================
21+ const rafRef = React . useRef < number > ( ) ;
22+ const cancelRaf = ( ) => {
23+ raf . cancel ( rafRef . current ) ;
24+ } ;
25+
2826 const doUpdate = useEvent ( ( ) => {
2927 setState ( nextValueRef . current ) ;
3028
@@ -34,24 +32,18 @@ export default function useDelayState<T>(
3432 } ) ;
3533
3634 const updateValue = useEvent ( ( next : T , immediately ?: boolean ) => {
35+ cancelRaf ( ) ;
36+
3737 nextValueRef . current = next ;
3838
3939 if ( next || immediately ) {
4040 doUpdate ( ) ;
41- setTimes ( false ) ;
4241 } else {
43- setTimes ( 0 ) ;
42+ rafRef . current = raf ( doUpdate ) ;
4443 }
4544 } ) ;
4645
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 , [ ] ) ;
5547
5648 return [ state , updateValue ] ;
5749}
0 commit comments