-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathuseThrottle.ts
36 lines (31 loc) · 990 Bytes
/
useThrottle.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
import { useEffect, useRef, useState } from 'react';
import useUnmount from './useUnmount';
const useThrottle = <T>(value: T, ms: number = 200) => {
const [state, setState] = useState<T>(value);
const timeout = useRef<ReturnType<typeof setTimeout>>();
const nextValue = useRef(null) as any;
const hasNextValue = useRef(0) as any;
useEffect(() => {
if (!timeout.current) {
setState(value);
const timeoutCallback = () => {
if (hasNextValue.current) {
hasNextValue.current = false;
setState(nextValue.current);
timeout.current = setTimeout(timeoutCallback, ms);
} else {
timeout.current = undefined;
}
};
timeout.current = setTimeout(timeoutCallback, ms);
} else {
nextValue.current = value;
hasNextValue.current = true;
}
}, [value]);
useUnmount(() => {
timeout.current && clearTimeout(timeout.current);
});
return state;
};
export default useThrottle;