Pull to refresh

Разбор debounce() в lodash

Функция debounce - это обёртка над вашей функцией, которая позволяет отменить и отложить на какое-то время её повторные вызовы разными способами.

Простой, но частоиспользующийся пример

Рассмотрим следующий код React приложения:

import { debounce } from "lodash";
import React, { useRef } from "react";

const HomePage = () => {
  const counter = useRef(1);

  const handleClick = debounce(
    (count) => {
      console.log("click happened!", count);
    },
  );

  return (
    <button
      onClick={() => {
        counter.current += 1;
        handleClick(counter.current); // Вызов функции №1
        handleClick(counter.current); // Вызов функции №2
        handleClick(counter.current); // Вызов функции №3
      }}
    >
      Click me
    </button>
  );
};

export default HomePage;

Здесь используется "записывающая" способность рефов в React. Если вы не знакомы с ней, прошу сначала прочитать официальную документацию.

Обёртка, в которую мы обернули нашу функцию отклоняет 2-ой и 3-ий вызов функции при клике на кнопку. А точнее она запоминает последний (3-ий) и затем выполняет его.


Зачастую в React приложении идёт многоповторный перерендеринг из-за частых изменений со стороны пользователя. Чтобы не нагружать систему, мы можем воспользоваться данной функцией. Чаще всего она может пригодиться в ситуации, когда пользователь вводит в input какое-либо содержимое и происходит ререндер при вводе каждого символа. Так как нам это не нужно, мы можем отложить его на n-ое количество времени.

Параметры функции

debounce(func, [time], [options])

func - функция, которую необходимо обернуть
time - время в миллисекундах до следующего вызова
options - набор дополнительных параметров в виде объекта

[options.leading] (boolean, false по-умолчанию) - если true, то разрешает запуск функции моментально, не дожидаясь выставленного в параметре time времени. Последующие вызовы будут отклоняться до тех пор пока не пройдёт заданное время. По истечению будет запущен последний вызов функции.

[options.maxWait] (number) - максимальное время которое функция не будет вызываться при её многократном вызове. Дело в том, что если функция будет вызываться чаще, заданного времени в параметре time, то таймер будет каждый раз сбрасываться и наша функция не будет выполнена до тех пор, пока на протяжении n времени её не будут трогать. Если мы задаём этот параметр, то когда истечёт заданное в нём время, функция будет принудительно вызвана.

[options.trailing] (boolean, true по-умолчанию) - противоположность leading.
Если задан как true, то разрешает запуск функции по прошествии заданного в параметре time времени. Если false, то соответственно запрещает.

Если мы одновременно зададим  { leading: true, trailing: true }, то у нас из одного вызова функции получится сразу два. Первый будет сразу, а второй по прошествии заданного времени.

Если всё ещё не понятно, то рекомендую запустить локально данный пример с разными настройками данной функции

  const handleClick = debounce(
    (count) => {
      console.log("click happened!", count);
    },
    3000,
    { leading: true, maxWait: 3500, trailing: true }
  );

Методы функции

Помимо параметров, данная функция имеет 2 метода:

cancel() - отменяет отложенный вызов до его запуска
flush() - наоборот, запускает отложенный вызов раньше времени

Добавим 2 элемента к предыдущему коду:

<button
  onClick={() => {
    handleClick.cancel();
  }}
  >
  Cancel
</button>

<button
  onClick={() => {
    handleClick.flush();
   }}
  >
  Call immediately
</button>

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.