【vue react 项目常用hooks】useDebounceVal

【vue react 项目常用hooks】useDebounceVal

我们经常需要对搜索进行防抖,有时还需要拿到防抖后的数据传递给下游组件,这个时候就需要用到这个 useDebounceVal,请看 vuereact 中分别如何实现。

1、分析

useDebounceVal 的输入是为防抖前的 val, 还有防抖duration,输出是一个防抖后的val.

所以函数是长这样:

ts 复制代码
declare function useDebounceVal<T>(val: T, duration: number): T;

debounce 可以自己实现,也可以使用 lodash 等工具。

需要注意的是,react 中需要实现 debouncecancel 函数, vue 可以不需要。

2、react 版

js 复制代码
import { useState, useEffect } from 'react';
import { debounce } from 'lodash-es';

export function useDebounceVal(value, delay = 500) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = debounce(() => {
      setDebouncedValue(value);
    }, delay);

    handler();
    return () => handler.cancel();
  }, [value, delay]);

  return debouncedValue;
}

使用方法:

js 复制代码
const [searchQuery, setSearchQuery] = useState('');
const debouncedSearchQuery = useDebounceVal(searchQuery);

3、vue 版

vue 版有2种,一种跟上面类似(普通版),还有一种是借助 customRef 来实现。分别如下:

3-1、普通版

js 复制代码
import { ref, watch } from 'vue';
import { debounce } from 'lodash-es';

export function useDebounceVal(value, delay = 500) {
  const debouncedValue = ref(value.value);

  const updateValue = debounce((newValue) => {
    debouncedValue.value = newValue;
  }, delay);

  watch(value, (newValue) => {
    updateValue(newValue);
  });

  return debouncedValue;
}

使用方法:

js 复制代码
const searchQuery = ref('');
const debouncedSearchQuery = useDebounceVal(searchQuery);

3-2、customRef版

js 复制代码
import { customRef } from 'vue';

export function useDebounceRef(value, delay = 500) {
  let timeout;
  return customRef((track, trigger) => {
    return {
      get() {
        track();
        return value;
      },
      set(newValue) {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          value = newValue;
          trigger();
        }, delay);
      },
    };
  });
}

使用方法:

js 复制代码
const searchQuery = useDebounceRef('');

4、分析2

看到这里有些同学可能还在疑惑,为啥要这个东西,不用可不可以。那我们先看看下面的情况。通常我们会把输入框和查询结果放到一起处理,如下:

jsx 复制代码
<div className='search-container'>
  <input
    type='text'
    value={searchQuery}
    onChange={handleInputChange}
    placeholder='请输入搜索内容'
  />
  <SearchResults searchQuery={debouncedSearchQuery} />
</div>

但有的时候,SearchResults 逻辑不是我们控制的(比如其他同事或者下游业务),或者是我们控制但是想把逻辑内聚到 SearchResults 组件里面。期望的效果是:我们只需要把 debouncedVal 数据传递给 SearchResults 就行了,于是就有了这个 hooks 的用武之地。

diff 复制代码
<div className='search-container'>
  <input
    type='text'
    value={searchQuery}
    onChange={handleInputChange}
    placeholder='请输入搜索内容'
  />
-  <SearchResults searchQuery={debouncedSearchQuery} />
+  <SearchResults searchVal={debouncedSearchVal} />
</div>

5、总结

本文分析了为啥需要 useDebounceVal,并编写了 vuereact 版的 useDebounceVal,有需要的自行取用。

全文完~~

相关推荐
golang学习记17 小时前
从0死磕全栈之Next.js App Router动态路由详解:从入门到实战
前端
huangql52017 小时前
基于前端+Node.js 的 Markdown 笔记 PDF 导出系统完整实战
前端·笔记·node.js
在逃的吗喽17 小时前
Vue3新变化
前端·javascript·vue.js
yqwang_cn17 小时前
打造优雅的用户体验:自定义jQuery工具提示插件开发全解析
前端·jquery·ux
小Tomkk17 小时前
AI 提效:利用 AI 从前端 快速转型为UI/UX设计师和产品
前端·人工智能·ui
Demoncode_y18 小时前
Vue3中基于路由的动态递归菜单组件实现
前端·javascript·vue.js·学习·递归·菜单组件
杨超越luckly18 小时前
HTML应用指南:利用POST请求获取全国中国工商农业银行网点位置信息
大数据·前端·html·数据可视化·银行网点
皮蛋瘦肉粥_12118 小时前
pink老师html5+css3day02
前端·css3·html5
qianmo202118 小时前
基于pycharm实现html文件的快速实现问题讨论
前端·html
IT_陈寒18 小时前
SpringBoot3踩坑实录:一个@Async注解让我多扛了5000QPS
前端·人工智能·后端