antd renderFormItem AutoComplete结合防抖导致防抖失效的解决办法

简介: antd renderFormItem AutoComplete结合防抖导致防抖失效的解决办法

业务背景

我们有一个需求是在用户输入用例名称的时候,系统根据名称去匹配公共用例库中的用例模块展示在下拉框中,然后用户可选择想要的模块导入其中的用例:

但是如果用户每输入一个字符就去调用接口查询的话,这样就太频繁了,会给服务端造成不小的压力,所以就需要使用防抖方法来进行限流控制。这里的方案如下:

因为antd提供了AutoComplete方法能够很方便的在表格中实现编辑行的操作,这里也就不重新造轮子了,然后结合lodash提供的debounce方法进行防抖设置,也就是每隔200毫秒去搜索一次,完整的代码如下:

const batchSearchDebounce = debounce(async (keyWords) => {
    if (keyWords) {
      return await searchComStdMod({ search: keyWords }).then((res) => {
        const data: any[] = [];
        res.data.forEach((item: any) => {
          data.push({
            label: (
              <>
                <Tag color="blue">公共模块</Tag>
                {item.label}
              </>
            ),
            value: item.value,
            name: item.label,
          });
        });
        setSearchData(data);
      });
    }
  }, 200);
   <AutoComplete
        style={{ width: width }}
        placeholder="请输入用例名称"
        onSelect={(_: any, mod: any) => {
          comStandardCasesAll({ module_id: mod.value }, REQ_LIST).then((res) => {
            setFormData({ cases: res.data, module_name: mod.name });
            setVisible(true);
          });
        }}
        {...(type === 'single' ? {} : { value: batchData.value })}
        onChange={async (keyWords) => {
          batchData.onChange(keyWords);
          await batchSearchDebounce(keyWords); //防抖会失效
        }}
        options={searchData}
      />

但在使用的过程中发现防抖并没有生效,我每输入一个文字就会搜索一次,1秒内输入10下就会有10个请求发出去:

造成这个问题的原因是什么呢

是因为AutoComplete中的onChange的事件,当每次改变的时候都会创建一个debounce方法,所以onChange事件触发10次,就会有10个防抖函数并执行。

如何解决

我们可以使用useCallback将防抖方法进行缓存,避免不必要的刷新重建就可以了。

如下所示,useCallback有两个参数:

useCallback(fn, deps)`

fn:要缓存的函数,在初始渲染期间,React将返回你的函数。在下一次渲染时,如果依赖关系(也就是deps)自上次渲染以来没有改变,React将再次给你相同的函数。

deps: 是一个数组,当里面的元素发生改变的时候会重新渲染函数。

因为,我们结合useCallback这里我们将batchSearchDebounce 做一下修改即可:

const batchSearchDebounce = useCallback(
    debounce(async (keyWords: string) => {
      if (keyWords) {
        batchData.onChange(keyWords);
        return await searchComStdMod({ search: keyWords }).then((res) => {
          const data: any[] = [];
          res.data.forEach((item: any) => {
            data.push({
              label: (
                <>
                  <Tag color="blue">公共模块</Tag>
                  {item.label}
                </>
              ),
              value: item.value,
              name: item.label,
            });
          });
          setSearchData(data);
        });
      }
    }, 200),
    [],
  );

使用useCallback之后就不会出现上述的问题了,防抖方法也就生效了:

useCallback 它可以让你在重新渲染之间缓存函数,避免函数冗余的重新渲染,以此来提高性能,没想到因为这样的机制也能解决掉一些逻辑问题。

目录
相关文章
UMI多环境配置
一般来说项目不止有dev和prod两个环境,umi可以通过环境变量 UMI_ENV 区分不同环境来指定配置。
1805 0
|
7月前
|
Java 关系型数据库 MySQL
零基础入门 Go 语言
Go语言以其高性能、原生并发和极简语法成为云原生开发的新宠。本文全面介绍了Go的核心特性,包括环境搭建、基础语法、函数、结构体与接口等核心概念,重点解析了goroutine和channel的并发模型。通过对比Java,展示了Go在部署、并发和语法简洁性上的优势,并提供了HTTP服务器和MySQL操作等实战案例。文章还总结了Go开发的最佳实践,帮助开发者快速掌握这门高效的后端开发语言。
904 1
|
移动开发 数据挖掘 开发者
服务器发送事件(SSE)在现代Web开发中的关键作用
服务器发送事件(SSE)是HTML5标准协议,用于服务器主动向客户端推送实时数据,适合单向通信场景。相比WebSocket,SSE更简洁高效,基于HTTP协议,具备自动重连、事件驱动等特性。常见应用场景包括实时通知、新闻推送、数据分析等。通过Apipost等工具可轻松调试SSE,助力开发者构建高效实时Web应用。示例中,电商平台利用SSE实现秒杀活动通知,显著减少延迟并简化架构。掌握SSE技术,能大幅提升用户体验与开发效率。
|
前端开发
react antd点击table行时加选中背景色
react antd点击table行时加选中背景色
527 5
|
机器人 API
自定义飞书Webhook机器人api接口
自定义飞书Webhook机器人api接口
1668 25
|
前端开发 JavaScript
如何在 CSS3 动画中添加缓动效果?
在上述示例中,页面中有一个蓝色的方块元素和几个按钮,点击不同的按钮可以为方块的移动动画设置不同的缓动效果。通过JavaScript获取方块元素,根据用户点击按钮传递的缓动函数值,修改方块的`transitionTimingFunction`属性,从而实现动态切换缓动效果的功能。每次点击按钮后,方块会向右移动100px,并在1秒后回到初始位置,以便用户观察不同缓动效果下的动画表现。
445 45
|
JavaScript
js监听页面或元素scroll事件,滚动到底部或顶部
js监听页面或元素scroll事件,滚动到底部或顶部
1858 0
js监听页面或元素scroll事件,滚动到底部或顶部
|
JavaScript 前端开发 索引
JavaScript 数组方法 slice() 的 5 个示例
slice() 方法将数组部分的副本返回到新的数组对象中。这个对象是从 start 到 end 选择的。需要注意的是,此方法不会修改原始数组。此外,如果向其中一个数组添加新元素,则另一个数组不会受到影响。
991 0
JavaScript 数组方法 slice() 的 5 个示例