@@ -6,28 +6,32 @@ export type Updater<State> = (prev: State) => State;
6
6
export function useFrameState < State > (
7
7
defaultState : State ,
8
8
) : [ State , ( updater : Updater < State > ) => void ] {
9
- const [ state , setState ] = useState < State > ( defaultState ) ;
9
+ const stateRef = useRef ( defaultState ) ;
10
+ const [ , forceUpdate ] = useState ( { } ) ;
10
11
11
12
const timeoutRef = useRef < number > ( null ) ;
12
- const tmpStateRef = useRef < State > ( null ) ;
13
+ const updateBatchRef = useRef < Updater < State > [ ] > ( [ ] ) ;
13
14
14
15
function setFrameState ( updater : Updater < State > ) {
15
16
if ( timeoutRef . current === null ) {
16
- tmpStateRef . current = state ;
17
+ updateBatchRef . current = [ ] ;
17
18
timeoutRef . current = raf ( ( ) => {
18
- setState ( tmpStateRef . current ) ;
19
+ updateBatchRef . current . forEach ( batchUpdater => {
20
+ stateRef . current = batchUpdater ( stateRef . current ) ;
21
+ } ) ;
19
22
timeoutRef . current = null ;
23
+ forceUpdate ( { } ) ;
20
24
} ) ;
21
25
}
22
26
23
- tmpStateRef . current = updater ( tmpStateRef . current ) ;
27
+ updateBatchRef . current . push ( updater ) ;
24
28
}
25
29
26
30
useEffect ( ( ) => {
27
31
raf . cancel ( timeoutRef . current ) ;
28
32
} , [ ] ) ;
29
33
30
- return [ state , setFrameState ] ;
34
+ return [ stateRef . current , setFrameState ] ;
31
35
}
32
36
33
37
/** Lock frame, when frame pass reset the lock. */
0 commit comments