Skip to main content

Що робить useMemo()?

Що робить 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 (він кешує саму функцію)

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

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

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