| import debounce from 'lodash/debounce'; |
| import React, { useState, useCallback } from 'react'; |
| import type { SetterOrUpdater } from 'recoil'; |
| import type { TSetOption } from '~/common'; |
| import { defaultDebouncedDelay } from '~/common'; |
|
|
| |
| |
| |
| function useDebouncedInput<T = unknown>({ |
| setOption, |
| setter, |
| optionKey, |
| initialValue, |
| delay = defaultDebouncedDelay, |
| }: { |
| setOption?: TSetOption; |
| setter?: SetterOrUpdater<T>; |
| optionKey?: string | number; |
| initialValue: T; |
| delay?: number; |
| }): [ |
| (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | T) => void, |
| T, |
| SetterOrUpdater<T>, |
| |
| ] { |
| const [value, setValue] = useState<T>(initialValue); |
|
|
| |
| |
| |
| const setDebouncedOption = useCallback( |
| debounce(setOption && optionKey ? setOption(optionKey) : setter, delay), |
| [], |
| ); |
|
|
| |
| const onChange = useCallback( |
| (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | T) => { |
| const newValue: T = |
| typeof e !== 'object' |
| ? e |
| : ((e as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>)?.target |
| .value as unknown as T); |
| setValue(newValue); |
| setDebouncedOption(newValue); |
| }, |
| [setDebouncedOption], |
| ); |
| return [onChange, value, setValue]; |
| } |
|
|
| export default useDebouncedInput; |
|
|