Skip to main content

Коли використовувати useCallback()?

Коли використовувати useCallback()

Хук useCallback() потрібен не для прискорення функції, а для того, щоб зберігати одне й те саме посилання на функцію між рендерами.

Це важливо, коли:

  1. Функція передається в дочірній компонент, особливо якщо він обгорнутий у React.memo.
  2. Функція використовується в useEffect / useMemo і повинна залишатися стабільною (щоб не викликати ефект заново).
  3. Ти хочеш уникнути зайвого пересоздання функцій при кожному рендері (що призводить до непотрібних перемальовувань).

Приклад 1: передача функції в React.memo-компонент

javascript
const Button = React.memo(({ onClick }) => { console.log("Ререндер кнопки"); return <button onClick={onClick}>+</button>; }); function Counter() { const [count, setCount] = useState(0); // Без useCallback → при кожному рендері створюється нова функція const increment = useCallback(() => setCount(c => c + 1), []); return ( <div> <p>{count}</p> <Button onClick={increment} /> </div> ); }

Тут:

  • increment створюється один раз, оскільки залежності - [].
  • Кнопка не перерендерюється без причини. Без useCallback Button ререндерилась би при кожній зміні count.

Приклад 2: стабільна залежність у useEffect

javascript
function FetchUser({ id }) { const fetchUser = useCallback(() => { return fetch(`/api/user/${id}`).then(res => res.json()); }, [id]); useEffect(() => { fetchUser(); }, [fetchUser]); // useEffect викличеться тільки при зміні id }

Без useCallback fetchUser пересоздавалась би кожен рендер, і useEffect викликався б кожного разу - навіть якщо id не змінився.


Підсумок - коли реально варто використовувати

СитуаціяЧи варто використовувати?Чому
Передаєш функцію в React.memo компонентТакУникаєш зайвих ререндерів
Використовуєш функцію в useEffect / useMemoТакСтабілізуєш залежність
Виклик функції прямо всередині JSXНіНемає сенсу, вона не зберігається
Функція не залежить від пропсів чи стануМожна з []Створиться тільки один раз
Легка функція, що не впливає на іншихНіОптимізація не виправдана

Що станеться, якщо не вказати залежності

javascript
const memoizedFn = useCallback(() => { doSomething(a, b); });

Без масиву залежностей:

  • useCallback буде пересоздавати функцію на кожному рендері - тобто ніякої мемоізації не відбудеться.

  • Це еквівалентно простому написанню:

    javascript
    const memoizedFn = () => doSomething(a, b);

Щоб useCallback працював, потрібно передати залежності, за якими React розумітиме, коли функція дійсно повинна оновитися.


Приклад із залежностями

javascript
const handleClick = useCallback(() => { console.log(count); }, [count]);
  • Функція пересоздається тільки якщо змінився count.
  • Якби ти не вказав [count], то всередині функції завжди був би "заморожений" count з першого рендера.

Важливо пам'ятати

ПравилоПояснення
useCallback(fn, deps) кешує посилання на функціюФункція створюється заново тільки при зміні залежностей
Якщо пропустити залежностіФункція буде пересоздаватися при кожному рендері (мемоізація не працює)
Якщо поставити []Функція створюється один раз при монтуванні і ніколи не оновлюється
Вказуй усі значення, що використовуються всерединіІнакше замикання міститиме застарілі дані

Підсумок

ПитанняВідповідь
Коли використовувати useCallback()Коли потрібно, щоб функція зберігала посилання між рендерами (React.memo, useEffect, useMemo)
Що станеться без залежностейФункція буде пересоздаватися кожен рендер - мемоізація не працює
Що буде з []Функція створиться один раз і ніколи не оновиться
Що повертаєТу саму функцію, але з мемоізованим посиланням

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.