reactjs - lodash debounce 可以在无状态 React 组件中使用而不使用 hooks 吗?

标签 reactjs lodash

我想使用 lodash debounce 来防止按钮 onClick 在多次快速点击时多次运行。该按钮位于无状态功能组件中,根据我的阅读( in this SO question ),debounce 在功能组件中不起作用,因为每次渲染时 debounce 函数都是新的。

解决这个问题的一种方法似乎是使用 useCallback React hook,但不幸的是,该项目目前的版本为 React 15.6.1,此时升级不可行。如果我将组件转换为有状态组件或者传入一个已经去抖动的提交函数,我也可以让去抖动工作,但我认为最好的情况结果是维护功能组件,同时仍然具有它能够防止任何提交功能的多次提交。

是否可以在功能组件内使用钩子(Hook)来实现去抖动?

这是我的功能组件,防抖不起作用:

import * as React from 'react';
import * as Lodash from 'lodash';
import { Button } from 'react-bootstrap';
import { Modal } from 'react-bootstrap';

export const ConfirmSubmitModal = props => {
    const { submit } = props;

    const debouncedSubmit = Lodash.debounce(() => {
        submit();
    }, 3000, { "leading": true, "trailing": false });

    return (
        <div>
            <Modal>
                  <Button onClick={debouncedSubmit}>Submit</Button>
            </Modal>
        </div>
    );
};

最佳答案

您可以使用_.memoize()创建类似于useCallback钩子(Hook)的东西。只要通过 props 传递的 submit 函数不会改变,getDebouncedSubmit 将返回相同的 debounced 函数。

_.memoize.Cache = WeakMap; // use a weak map as _.memoize cache to prevent memory leaks

const getDebouncedSubmit = _.memoize(submit => 
  _.debounce(() => {
    submit();
  }, 3000, { "leading": true, "trailing": false })
);

const ConfirmSubmitModal = ({ submit }) => {
  const debouncedSubmit = getDebouncedSubmit(submit);

  return (
    <div>
      <button onClick={debouncedSubmit}>Submit</button>
    </div>
  );
};

const submit = () => console.log('clicked');

ReactDOM.render(
  <ConfirmSubmitModal submit={submit} />,
  demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="demo"></div>

关于reactjs - lodash debounce 可以在无状态 React 组件中使用而不使用 hooks 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59060703/

相关文章:

javascript - 如何防止图像在 react native 中的 uri 重新加载时闪烁?

javascript - ReactJS 删除组件

reactjs - 不可草拟值的大小写缩减器不得返回未定义

javascript - 为什么我不能链接这一系列的 lodash 调用?

javascript - 映射对象内的数组

javascript - 使用对象引用进行过滤 lodash

javascript - 在路由组件之外 react 路由器重定向

javascript - 如何在 Material UI 中设置 Material 卡的最小高度?

javascript - 使用 Lodash 的递归映射

javascript - 比较 2 个对象数组。按 ids 匹配,将对象属性插入数组