如何在函数组件中使用防抖

为什么函数组件不能像类组件一样直接对方法进行节流处理

  • 无效代码

import React, {useState} from "react";
import debounce from 'lodash/debounce';
const sendQuery = (query) => console.log(`Querying for ${query}`);
const Search = () => {
  const [userQuery, setUserQuery] = useState("");
  const delayedQuery = debounce(q => sendQuery(q), 500);
  const onChange = e => {
    setUserQuery(e.target.value);
    delayedQuery(e.target.value);
  };
  return (
    <div>
      <label>Search:</label>
      <input onChange={onChange} value={userQuery} />
    </div>
  );

因为函数组件每次重绘都会导致在函数内部定义的变量都会被重新初始化。这就意味着,每次我们调用debounce函数时都会重新注册一个setTimeout回调。这样子做防抖函数并没有发挥作用,仅仅是把反应时间延后了500毫秒。

解决方案

自定义hooks(useDebounce)

  • 使用
const callback = useDebounce(fn, [(wait = 0)]);
  • 自定义hooks
import { useRef, useCallback, useEffect } from 'react';

export default function useDebounce(fn, wait = 0) {
	useEffect(
	    () => {
	      return cancel;
	    },
	    // eslint-disable-next-line react-hooks/exhaustive-deps
    	[]
    );
  	const timerRef = useRef(0);
  	const cancel = useCallback(() => {
	    if (timerRef.current) {
	      clearTimeout(timerRef.current);
	      timerRef.current = 0;
	    }
  	}, []);
  	const callback = useCallback(
    	(...args) => {
      		cancel();
      		timerRef.current = setTimeout(fn, wait, ...args);
    	},
    [cancel, fn, wait]
  	);
  return callback;
}

使用useCallback

const delayedQuery = useCallback(debounce(q => sendQuery(q), 500), []);

使用useRef

const SearchFixed = () => {
  const [userQuery, setUserQuery] = useState("");
  const delayedQuery = useRef(debounce(q => sendQuery(q), 500)).current;
  const onChange = e => {
    setUserQuery(e.target.value);
    delayedQuery(e.target.value);
  };
  return (
    <div>
      <label>Search Fixed:</label>
      <input onChange={onChange} value={userQuery} />
    </div>
  );
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MaxLoongLvs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值