forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
useDebouncedState.ts
35 lines (30 loc) · 1.32 KB
/
useDebouncedState.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
import debounce from 'lodash/debounce';
import {useEffect, useRef, useState} from 'react';
import CONST from '@src/CONST';
/**
* A React hook that provides a state and its debounced version.
*
* @param initialValue - The initial value of the state.
* @param delay - The debounce delay in milliseconds. Defaults to USE_DEBOUNCED_STATE_DELAY = 300ms.
* @returns A tuple containing:
* - The current state value.
* - The debounced state value.
* - A function to set both the current and debounced state values.
*
* @template T The type of the state value.
*
* @example
* const [value, debouncedValue, setValue] = useDebouncedState<string>("", 300);
*/
function useDebouncedState<T>(initialValue: T, delay: number = CONST.TIMING.USE_DEBOUNCED_STATE_DELAY): [T, T, (value: T) => void] {
const [value, setValue] = useState(initialValue);
const [debouncedValue, setDebouncedValue] = useState(initialValue);
const debouncedSetDebouncedValue = useRef(debounce(setDebouncedValue, delay)).current;
useEffect(() => () => debouncedSetDebouncedValue.cancel(), [debouncedSetDebouncedValue]);
const handleSetValue = (newValue: T) => {
setValue(newValue);
debouncedSetDebouncedValue(newValue);
};
return [value, debouncedValue, handleSetValue];
}
export default useDebouncedState;