-
Notifications
You must be signed in to change notification settings - Fork 199
Expand file tree
/
Copy pathuseSyncState.ts
More file actions
34 lines (25 loc) · 977 Bytes
/
useSyncState.ts
File metadata and controls
34 lines (25 loc) · 977 Bytes
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
import * as React from 'react';
import useEvent from './useEvent';
type Updater<T> = T | ((prevValue: T) => T);
export type SetState<T> = (nextValue: Updater<T>) => void;
/**
* Same as React.useState but will always get latest state.
* This is useful when React merge multiple state updates into one.
* e.g. onTransitionEnd trigger multiple event at once will be merged state update in React.
*/
function useSyncState<T>(defaultValue?: T): [get: () => T, set: SetState<T>] {
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
const currentValueRef = React.useRef<T>(defaultValue);
const getValue = useEvent(() => {
return currentValueRef.current;
});
const setValue = useEvent((updater: Updater<T>) => {
currentValueRef.current =
typeof updater === 'function'
? (updater as (prevValue: T) => T)(currentValueRef.current)
: updater;
forceUpdate();
});
return [getValue, setValue];
}
export default useSyncState;