背景
本文是手写hooks系列第一期,欢迎大家在评论起积极评论留言,给出更优秀的实践。
现有输入框input,当用户在输入框中输入时触发onChange
事件,在onChange
事件中会触发后端接口请求。
现收到测试反馈,要求对输入框进行防抖,防止发送无效的请求,用户体验不好。
现在代码:
const Test = () => {
const [inputValue, setInputValue] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
useEffect(() => {
fetchApi(url, { params: { keyword: inputValue } });
}, [inputValue]);
return <input value={inputValue} onChange={handleChange} />;
};
复制代码
需求
现在要求实现自定义hook:useDebounce
,实现后具体用法应如下: 传入要防抖的值inputValue
和防抖时间,返回防抖后的值。
const Test = () => {
const [inputValue, setInputValue] = useState('');
const debouncedValue = useDebounce(inputValue,1000);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
useEffect(() => {
fetchApi(url, { params: { keyword: inputValue } });
}, [debouncedValue]); //通过debouncedValue来做到防抖的效果
return <input value={inputValue} onChange={handleChange} />;
};
复制代码
编码实现
第一步:先定义好输入输出结构。
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
return debouncedValue;
}
复制代码
第二步:对delay进行处理,这里的核心是在delay时间内,如果该值还没有发生变更,则在delay时间段过后返回该值。
在代码里面解读就是通过定时器来实现,如果有新的值传入则清除之前的定时器,执行新的定时器,时间到了就替换debouncedValue。
function useDebounce<T>(value: T, delay = 1000): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const handle = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handle);
}, [value, delay]);
return debouncedValue;
}
复制代码
完。