Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить useMemo()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Хук `useMemo()` **запам'ятовує (кешує)** результат обчислення функції і **повторно використовує його**, якщо залежності не змінилися. **Ключове:** useMemo потрібен, щоб не переобчислювати щось важке при кожному рендері, якщо вхідні дані не змінилися.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `useMemo()` Хук `useMemo()` **запам'ятовує (кешує)** результат обчислення функції і **повторно використовує його**, якщо залежності не змінилися. > Простіше кажучи: > `useMemo` потрібен, щоб **не переобчислювати щось важке** при кожному рендері, > якщо вхідні дані не змінилися. --- ## Синтаксис ```javascript const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` - Перший аргумент - функція, що повертає обчислюване значення. - Другий аргумент - масив залежностей. - React запам'ятовує результат цієї функції і **переобчислить його лише тоді**, коли зміниться хоча б одна із залежностей `[a, b]`. --- ## Простий приклад ```javascript import { useMemo, useState } from "react"; function Example() { const [count, setCount] = useState(0); const [text, setText] = useState(""); const expensiveCalculation = (num) => { console.log("Виконується важкий розрахунок..."); let result = 0; for (let i = 0; i < 1e7; i++) { result += num * 2; } return result; }; // useMemo запам'ятовує результат const result = useMemo(() => expensiveCalculation(count), [count]); return ( <div> <p>Результат: {result}</p> <button onClick={() => setCount(count + 1)}>+</button> <input value={text} onChange={(e) => setText(e.target.value)} /> </div> ); } ``` Що відбудеться: - "Важкий розрахунок" (`expensiveCalculation`) виконується **лише тоді**, коли змінюється `count`. - Зміна `text` **не переобчислює** `result`. - Це економить продуктивність при частих рендерах. --- ## Приклад без useMemo (погано) Якщо прибрати `useMemo`: ```javascript const result = expensiveCalculation(count); ``` Кожен рендер, навіть при зміні `text`, буде викликати `expensiveCalculation()` заново, навіть якщо `count` не змінювався. --- ## Коли корисний `useMemo` | Ситуація | Приклад | | --- | --- | | Важкі обчислення | сортування, фільтрація, великі цикли | | Обчислення похідних даних | наприклад, фільтрувати список користувачів за пошуком | | Оптимізація рендерів дочірніх компонентів | щоб не передавати новий об'єкт при кожному рендері | --- ### Приклад: запобігаємо непотрібним рендерам ```javascript function Parent({ users }) { const [filter, setFilter] = useState(""); // Без useMemo: новий масив створюється при кожному рендері // З useMemo: створюється тільки при зміні users або filter const filtered = useMemo( () => users.filter((u) => u.name.includes(filter)), [users, filter] ); return <UserList users={filtered} />; } ``` Якщо `UserList` обгорнутий у `React.memo`, він **не перерендериться**, поки `filtered` не зміниться. --- ## Важливо | Особливість | Пояснення | | --- | --- | | `useMemo` кешує **результат функції**, а не саму функцію | Для функцій - використовуй `useCallback` | | Використовуй тільки для **справді дорогих** обчислень | Не варто "обгортати все підряд" | | Працює **тільки при незмінних залежностях** | Якщо хоча б одна змінилася - переобчислення заново | --- ## Різниця між `useMemo` і `useCallback` | Хук | Що кешує | Повертає | | --- | --- | --- | | `useMemo` | результат функції | значення | | `useCallback` | саму функцію | функцію | Приклад: ```javascript const value = useMemo(() => compute(), [deps]); const fn = useCallback(() => doSomething(), [deps]); ``` --- ## Підсумок | Питання | Відповідь | | --- | --- | | Що робить `useMemo()` | Кешує результат функції, щоб не переобчислювати при кожному рендері | | Коли переобчислює | Коли змінюється хоча б одна залежність | | Що повертає | Збережене (мемоізоване) значення | | Навіщо потрібен | Для оптимізації важких обчислень і запобігання непотрібним ререндерам | | Не плутати з | `useCallback` (він кешує саму функцію) |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.