Для чего используется первый аргумент useCallback?

«Для чего используется первый аргумент useCallback?» — вопрос из категории JavaScript, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Первый аргумент useCallback — это функция, которую нужно мемоизировать (запомнить).

Основная цель: предотвратить создание новой идентичной функции при каждом рендере компонента React. Это критично для оптимизации, когда:

  1. Функция передаётся в качестве пропса (onClick, onChange) дочернему компоненту, обёрнутому в React.memo. Без useCallback дочерний компонент будет перерисовываться каждый раз, потому что получает новую ссылку на функцию, даже если её логика не изменилась.
  2. Функция является зависимостью других хуков, например, useEffect. Её стабильная ссылка предотвращает лишние срабатывания эффекта.

Пример:

import React, { useState, useCallback } from 'react';

const ExpensiveChild = React.memo(({ onAction }) => {
  console.log('Child rendered!');
  return <button onClick={onAction}>Click me</button>;
});

function ParentComponent() {
  const [count, setCount] = useState(0);

  // Без useCallback эта функция создавалась бы заново при каждом обновлении count
  const handleClick = useCallback(() => {
    console.log('Action performed, count is:', count);
  }, [count]); // Функция пересоздаётся только при изменении `count`

  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>Increment: {count}</button>
      <ExpensiveChild onAction={handleClick} />
    </div>
  );
}

Ключевой момент: useCallback возвращает мемоизированную версию функции, а не мемоизирует её результат (это делает useMemo). Второй аргумент — массив зависимостей — определяет, когда функцию нужно пересоздать.