可以在不使用钩子的无状态React组件中使用lodash防反跳吗?

时间:2019-11-26 23:07:48

标签: reactjs lodash

我想使用lodash debounce来防止多次多次快速单击时一次onClick按钮运行。该按钮位于无状态功能组件中,从我读过的内容(in this SO question)来看,debounce在功能组件中将不起作用,这是因为每个已渲染的防抖功能都是新功能。

解决这个问题的一种方法似乎是使用useCallback react钩子,但是不幸的是,该项目当前处于react版本15.6.1,并且目前不可行升级。如果将组件转换为有状态组件或传递已经去抖动的Submit函数,我也可以使debounce正常工作,但我认为最好的结果是在保持功能组件的同时保持其功能防止任何提交功能重复提交。

是否可以使用钩子使防抖功能在没有的功能组件内工作?

这是我的功能组件,无法进行防抖:

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>
    );
};

1 个答案:

答案 0 :(得分:3)

您可以使用useCallback创建类似于_.memoize()挂钩的内容。只要通过道具传递的submit函数不变,getDebouncedSubmit就会返回相同的去抖动函数。

_.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>