跳到主要内容

认识

一、认识


二、语法


2.1 useDebounce

2.2 useDebounceFn

const {
run,
cancel,
flush
} = useDebounceFn(
fn: (...args: any[]) => any,
options?: Options
);

2.3 useDebounceEffect

三、场景


3.1 对点击事件做防抖处理

背景:

当我们在函数组件中使用debounce的时候, 场景如下

import React from 'react';
import { debounce } from 'lodash';

function App() {
const onClick = debounce(
(e) => {
console.log(e);
},
3000,
{leading: true, trailing: false},
);

return (
<div className="App">
{num}
<button onClick={(e) => onClick(e)}>点击</button>
</div>
);
}

export default App;

我们多次点击事件, 通过debounce是可以轻松的做到防抖的。但是如果防抖函数中有更改状态的操作时:

import React, {useState} from 'react';
import {debounce} from 'lodash';

function App() {
const [num, setNum] = useState(0);
const onClick = debounce(
() => {
setNum(num + 1);
},
3000,
{leading: true, trailing: false},
);

return (
<div className="App">
{num}
<button onClick={(e) => onClick(e)}>点击</button>
</div>
);
}

export default App;

那么每一次状态的改变,都会重新调用函数组件,函数组件中的debounce函数会重建,所以导致平常用的debounce函数中的timer会成初始值,进而导致防抖失败。那么需要使用useMemo或者useCallback包裹debounce函数。所以下面使用useDebounceFn来实现React函数组件的防抖功能

解决

import React, {useState} from 'react';
import {useDebounceFn} from 'ahooks';

function App() {
const [num, setNum] = useState(0);
const onClick = useDebounceFn(
(e) => {
console.log(e);
setNum(num + 1);
},
{
wait: 3000,
leading: true,
trailing: false,
},
);

return (
<div className="App">
{num}
<button onClick={(e) => onClick.run(e)}>点击</button>
</div>
);
}

export default App;