import { useMemo, useCallback, useState, useRef, useEffect, ChangeEvent, Dispatch, SetStateAction } from "react"; import { noop, debounce } from "lodash-es"; export type UseDebounceResult = { inputValue: string; onEventChanged: (event: ChangeEvent | Partial>) => void; clearValue: () => void; updateValue: Dispatch>; }; export default function useDebounceEvent({ delay = 0, onChange, initialStateValue = "", trim }: { onChange: (value: string) => void; initialStateValue?: string; delay?: number; trim?: boolean; }) { const [inputValue, setValue] = useState(initialStateValue); const previousValue = useRef(null); useEffect(() => { previousValue.current = initialStateValue; }); const debounceCallback = useMemo(() => { if (!delay) { return onChange; } if (!onChange) { return noop; } return debounce(onChange, delay); }, [onChange, delay]); const onEventChanged = useCallback( (event: ChangeEvent | Partial>) => { const { value } = event.target; const finalValue = trim ? value.trim() : value; setValue(finalValue); debounceCallback(finalValue); }, [debounceCallback, setValue, trim] ); const clearValue = useCallback(() => { setValue(""); if (onChange) { onChange(""); } }, [setValue, onChange]); if (initialStateValue !== previousValue.current && initialStateValue !== inputValue) { setValue(initialStateValue); } return { inputValue, onEventChanged, clearValue, updateValue: setValue }; }