Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить useCallback()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useCallback()`** - це хук мемоізації функцій. Він повертає ту саму функцію (за посиланням) між рендерами, якщо залежності не змінилися. **Ключове:** `useCallback` не пришвидшує виконання функції, він лише зберігає посилання стабільним, щоб мемоізований дочірній компонент (`React.memo`) не ререндерився через "нову" функцію.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `useCallback()` `useCallback()` - це **хук мемоізації функцій**. Він **повертає ту саму функцію (за посиланням)** між рендерами, якщо залежності не змінилися. --- ### Синтаксис: ```javascript const memoizedCallback = useCallback(callback, [deps]); ``` - `callback` - сама функція, яку ти хочеш "запам'ятати". - `[deps]` - масив залежностей, від яких залежить ця функція. --- ### Приклад без `useCallback` ```javascript function App() { const handleClick = () => console.log('click'); return <Button onClick={handleClick} />; } ``` Щоразу, коли компонент `App` ререндериться, React **створює нову функцію** `handleClick`. Навіть якщо логіка всередині не змінилася - **посилання інше**. Якщо `Button` мемоізований (`React.memo`), React подумає: > «Проп `onClick` змінився (нове посилання) - потрібно ререндерити дитину.» Підсумок: `Button` **зайвий ререндер**. --- ### З `useCallback` ```javascript function App() { const handleClick = useCallback(() => console.log('click'), []); return <Button onClick={handleClick} />; } ``` Тепер: - `handleClick` створюється **один раз**; - При наступному рендері React **поверне те саме посилання** (якщо залежності не змінилися); - Для дочірнього `React.memo`-компонента проп `onClick` **не змінився**; - -> **дочірній компонент не ререндериться**. --- ## Як це працює "під капотом" React зберігає "стару" версію функції в пам'яті. При наступному рендері: - Порівнює залежності `[deps]`; - Якщо **нічого не змінилося**, повертає **старе посилання на функцію** з пам'яті; - Якщо хоча б одна залежність змінилася - створює нову функцію і запам'ятовує її. --- ## Приклад наочно ```javascript function Parent() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { console.log('clicked'); }, []); // залежності порожні -> посилання стабільне console.log('Parent render'); return ( <> <Child onClick={handleClick} /> <button onClick={() => setCount(c => c + 1)}>+</button> </> ); } const Child = React.memo(({ onClick }) => { console.log('Child render'); return <button onClick={onClick}>Child</button>; }); ``` **Без** `useCallback`**:** ```javascript Parent render Child render Parent render Child render (зайвий) ``` **З** `useCallback`**:** ```javascript Parent render Child render Parent render (Child не ререндериться) ``` --- ## Коли `useCallback` реально допомагає Використовуй, якщо: 1. Колбек передається **в мемоізований дочірній компонент** (`React.memo`, `useMemo` тощо); 2. Колбек бере участь **у залежностях іншого** `useEffect` **/** `useMemo`, і ти хочеш уникнути хибних перезапусків. --- ## Коли `useCallback` **не потрібен** - Якщо функція **використовується тільки всередині** компонента (у JSX не передається в дочірні). - Якщо **дитина не мемоізована** (`React.memo` немає). - Якщо компонент і так **ререндериться завжди** (наприклад, у батька немає оптимізації). > `useCallback` не пришвидшує виконання функції. > Він лише **зберігає посилання**, щоб React не думав, що вона "нова". --- ## Паралель з `useMemo` | Хук | Що кешує | Повертає | |---|---|---| | `useMemo(fn, deps)` | результат обчислення | **значення** | | `useCallback(fn, deps)` | саму функцію | **функцію** | Приклад еквівалентності: ```javascript useCallback(fn, deps) ≡ useMemo(() => fn, deps); ``` --- ## Часті неточності у використанні Невірні залежності: Якщо ти не додаси залежності, React буде використовувати **застарілі дані** із замикання. ```javascript // залежність count не вказана -> замикання const onClick = useCallback(() => console.log(count), []); ``` Правильно: ```javascript const onClick = useCallback(() => console.log(count), [count]); ``` --- ## Підсумок | Що робить `useCallback` | Як допомагає | |---|---| | Кешує функцію між рендерами | Уникає зайвого створення функцій | | Повертає те саме посилання, якщо залежності не змінилися | Пропси у дочірніх компонентів не "змінюються" | | Працює в парі з `React.memo` | Дозволяє реально уникнути ререндеру дитини | | Не пришвидшує код, не зменшує навантаження на CPU | Тільки стабілізує посилання |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.