我想使用 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/