← Назад к вопросам

В каких случаях нужно использовать UseCallback

2.0 Middle🔥 251 комментариев
#React#Оптимизация и производительность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

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

1. Передача функций в оптимизированные дочерние компоненты (React.memo)

Если вы оборачиваете дочерний компонент в React.memo, он повторно рендерится только при изменении его пропсов. Без useCallback функция, переданная как пропс, будет создаваться заново при каждом рендере родителя, что приводит к ложным срабатываниям и ненужным ререндерам.

import React, { useCallback } from 'react';

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

const ParentComponent = () => {
  const [count, setCount] = React.useState(0);
  
  // Без useCallback эта функция создаётся заново при каждом рендере ParentComponent
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []); // Зависимости пусты, функция мемоизируется навсегда

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count +基层组织1)}>Increment</button>
      <ChildComponent onClick={handleClick} />
    </div>
  );
};

Здесь ChildComponent не будет ререндериться при изменении count, так как handleClick остаётся той же ссылкой благодаря useCallback.

2. Зависимости в других хуках (useEffect, useMemo)

Когда функция используется в массиве зависимостей useEffect или useMemo, и она создаётся внутри компонента, её нужно мемоизировать, чтобы избежать бесконечных циклов или лишних вычислений.

const Example = ({ userId }) => {
  const [data, setData] = React.useState(null);
  
  const fetchData = useCallback(async () => {
    const response = await fetch(`/api/user/${userId}`);
    setData(await response.json());
  }, [userId]); // Зависимость от userId, функция обновится только при его изменении

  React.useEffect(() => {
    fetchData();
  }, [fetchData]); // Без useCallback useEffect срабатывал бы при каждом рендере

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
};

Если не использовать useCallback, fetchData менялась бы каждый раз, вызывая useEffect бесконечно.

3. Колбэки в интерактивных списках или формах

В динамических списках (например, рендеримых через map) каждая функция-обработчик должна быть стабильной, чтобы не вызывать ререндеры всех элементов при обновлении родителя.

const List = ({ items }) => {
  const handleItemClick = useCallback((id) => {
    console.log(`Item ${id} clicked`);
  }, []); // Функция не зависит от состояния, стабильна

  return (
    <ul>
      {items.map(item => (
        <ListItem key={item.id} item={item} onClick={handleItemClick} />
      ))}
    </ul>
  );
};

Когда НЕ нужно использовать useCallback:

  • В простых компонентах без ререндеров: Если компонент редко обновляется или не имеет дорогих дочерних элементов, useCallback добавляет лишнюю сложность.
  • Функции без зависимостей в простых обработчиках: Для однократных событий, не передаваемых в React.memo компоненты, можно обойтись без него.
  • Если функция часто меняет зависимости: В таких случаях мемоизация бесполезна, так как функция всё равно будет пересоздаваться.

Ключевой принцип:

useCallback следует применять только при реальных проблемах производительности, выявленных через профилирование (React DevTools). Необоснованное использование приводит к: .

  • Избыточному потреблению памяти (кеширование функций).
  • Усложнению кода.

Итог: Используйте useCallback для стабилизации ссылок на функции, когда это критично для предотвращения ререндеров или управления зависимостями хуков. В остальных случаях предпочитайте простые inline-функции для читаемости.