手写hooks系列第一期,实现防抖hook:useDebounce

背景

本文是手写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;
}
复制代码

完。

猜你喜欢

转载自juejin.im/post/7082424970910892045