React хук useMemo
Хук React useMemo
повертає мемоізоване значення.
Подумайте про запам’ятовування як про кешування значення, щоб його не потрібно було перераховувати.
Хук useMemo
запускається, лише коли оновлюється одна з його залежностей.
Це може покращити продуктивність.
Хуки useMemo
та useCallback
подібні. Основна відмінність полягає в тому, що useMemo
повертає мемоізоване значення, а useCallback
повертає мемоізовану функцію. Ви можете дізнатися більше про useCallback
у розділі useCallback.
Продуктивність
Хук useMemo
можна використовувати, щоб запобігти непотрібному запуску дорогих, ресурсомістких функцій.
У цьому прикладі ми маємо марнотратну функцію, яка виконується під час кожного рендера.
Змінюючи кількість або додаючи завдання, ви помітите затримку у виконанні.
Приклад:
Погана функція. Функція expensiveCalculation
запускається на кожному рендері:
import { useState } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = expensiveCalculation(count);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "Нове Todo"]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Додати Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Марнотратний розрахунок</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Використовуйте useMemo
Щоб розв’язати цю проблему продуктивності, ми можемо використати хук useMemo
, щоб запам’ятати функцію expensiveCalculation
. Це призведе до запуску функції лише за потреби.
Ми можемо завершити марнотратний виклик функції за допомогою useMemo
.
Хук useMemo
приймає інший параметр для оголошення залежностей. Марнотратна функція запускатиметься лише тоді, коли зміниться її залежність.
У наступному прикладі марнотратна функція запускатиметься лише тоді, коли буде змінено count
, а не буде додано завдання.
Приклад:
Приклад продуктивності за допомогою хука useMemo
:
import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = useMemo(() => expensiveCalculation(count), [count]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Марнотратний розрахунок</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Розрахунок...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);