Что такое useCallback

Ответ

useCallback — это хук React, который мемоизирует функцию, предотвращая её пересоздание при каждом рендере. Это полезно для оптимизации производительности, особенно когда функция передаётся в дочерние компоненты, зависящие от сравнения пропсов (например, React.memo или useEffect).

Пример:

const MyComponent = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []); // Зависимости пусты — функция создаётся один раз

  return <Child onClick={handleClick} />;
};

Когда использовать:

  • Функция передаётся в оптимизированный дочерний компонент (React.memo).
  • Функция используется в зависимостях хуков (например, useEffect).

Важно: Не злоупотребляйте useCallback — лишняя мемоизация может ухудшить производительность.

Ответ 18+ 🔞

А, слушай, вот этот useCallback — это такая штука, которая не даёт твоей функции перерождаться как проклятой на каждом чихе. Представь: у тебя в компоненте есть функция, и с каждым рендером React её тупо выкидывает и создаёт заново, как одноразовую. А если эту функцию жрёт дочерний компонент, обёрнутый в React.memo, то он, дурак, получает новую ссылку и думает: «О, пропсы изменились!», и перерисовывается просто так, на ровном месте. Пиздец, да?

Вот чтобы этого не было, ты эту функцию заворачиваешь в useCallback. Он её запоминает и отдаёт ту же самую, пока не изменятся зависимости, которые ты ему укажешь.

Смотри, как это выглядит:

const MyComponent = () => {
  const [count, setCount] = useState(0);

  // Вот эта хуйня теперь не будет создаваться заново, пока массив зависимостей пустой
  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []); // <- Видишь эти пустые скобки? Вот это и есть массив зависимостей.

  return <Child onClick={handleClick} />;
};

Так когда же эту штуку впихивать? Да в двух основных случаях, блядь:

  1. Когда ты передаёшь функцию в компонент, обёрнутый в React.memo. Без useCallback вся оптимизация насмарку, потому что ребёнок будет получать новую функцию каждый раз и перерисовываться. Полный пиздец и мартышлюшка.
  2. Когда твоя функция — зависимость другого хука, например, useEffect. А то получится, что эффект будет срабатывать на каждом рендере, потому что он видит новую функцию. Удивление пиздец, а потом волнение ебать — «почему у меня всё циклится?!».

Но вот что, ёпта, главное — не начинай это хуёво на всё подряд лепить. Сама мемоизация тоже требует ресурсов. Если компонент простой и перерисовывается нечасто, то useCallback может оказаться медленнее, чем просто новая функция. Это как пытаться оптимизировать табуретку для космического корабля — смысла ноль ебать. Сначала измерь, потом решай, куда эту штуку пихать.