Как работает useCallback в React и зачем он нужен
useCallback — это хук в React, который позволяет мемоизировать (запоминать) функцию между рендерами компонента.
Он возвращает ту же версию функции, если зависимости не изменились, и предотвращает создание новой функции при каждом рендере.
Зачем нужен useCallback
В JavaScript функции — это объекты по ссылке. Каждый раз, когда компонент рендерится, создаётся новая функция:
const handleClick = () => console.log("clicked"); // новая функция на каждый рендер
Если эту функцию вы передаёте в дочерний компонент, он будет ререндериться, даже если ничего по факту не поменялось.
Хук useCallback
нужен, чтобы избежать этой проблемы:
const handleClick = useCallback(() => {
console.log("clicked");
}, []);
Теперь handleClick
будет иметь ту же ссылку, пока зависимости в массиве не изменятся.
Синтаксис
const memoizedCallback = useCallback(() => {
// функция
}, [dependencies]);
-
() => {}
— функция, которую мы хотим мемоизировать -
[dependencies]
— массив зависимостей, как в useEffect
Пример: без useCallback
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log("Clicked");
};
return (
<>
<Child onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>+1</button>
</>
);
}
const Child = React.memo(({ onClick }) => {
console.log("🔁 Child rerendered");
return <button onClick={onClick}>Click me</button>;
});
Даже при изменении count
, Child
ререндерится, потому что handleClick
— новая ссылка.
Пример: с useCallback
const handleClick = useCallback(() => {
console.log("Clicked");
}, []);
Теперь Child
не ререндерится, потому что onClick
не меняется.
Когда использовать useCallback
Используйте, если:
- Вы передаёте функцию в
React.memo
-компонент - Функция используется в зависимости других хуков (
useEffect
,useMemo
)
Не нужно использовать useCallback:
- На каждый обработчик "на всякий случай"
- В простых компонентах, где ререндеры не критичны
useCallback vs useMemo
useCallback | useMemo | |
---|---|---|
Что возвращает | Возвращает функцию | Возвращает значение |
Пример | () => | heavyComputation() |
Применение | Используется для обработчиков | Используется для значений |
Совет:
useCallback
— это инструмент оптимизации, а не обязательный инструмент. Используйте его, когда есть конкретная необходимость в контроле ссылок на функции.