useMemo() — это ловушка, используемая в функциональном компоненте реакции, которая возвращает запомненное значение.
В компьютерных науках мемоизация — это концепция, используемая в целом, когда нам не нужно повторно вычислять функцию с заданным аргументом в следующий раз, поскольку она возвращает кешированный результат.
Запоминаемая функция запоминает результаты вывода для заданного набора входных данных.
Например, если есть функция для сложения двух чисел, и мы задаем параметр как 10 и 20 в первый раз, функция сложит эти два числа и вернет 30, но если те же входные данные поступят снова, мы вернем кешированный значение, т.е. 30, и больше не вычислять с помощью функции добавления.
В реакции мы также используем эту концепцию, всякий раз, когда в компоненте React состояние и реквизиты не изменяют компонент, и компонент не перерисовывается, он показывает тот же результат.
Хук useMemo используется для повышения производительности в нашем приложении React.
const memoizedValue = useMemo(functionThatReturnsValue, arrayDepencies)
Без использованияMemo()
Хук useMemo
можно использовать для предотвращения ненужного запуска дорогостоящих, ресурсоемких функций.
В этом примере у нас есть функция расчета, которая запускается при каждом рендеринге.
При изменении счетчика или добавлении задачи вы заметите задержку в выполнении.
import { useState } from "react"; import ReactDOM from "react-dom/client"; const App = () => { const [count, setCount] = useState(0); const [todo, setTodo] = useState([]); const calculation = calculation(count); const increment = () => { setCount((c) => c + 1); }; const addTodo = () => { setTodo((t) => [...t, "New Todo"]); };
const calculation = (num) => { console.log("Calculating..."); for (let i = 0; i < 1000000000; i++) { num += 1; } return num; };
return ( <div> <div> <h2>My Todos</h2> {todo.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>Calculation</h2> {calculation} </div> </div> ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
С использованиемMemo()
Чтобы решить эту проблему с производительностью, мы можем использовать хук useMemo
, чтобы запомнить функцию calculation
. Это приведет к тому, что функция будет работать только тогда, когда это необходимо.
Мы можем обернуть вызов функции вычисления с помощью useMemo
.
useMemo
Hook принимает второй параметр для объявления зависимостей. Функция вычисления будет работать только тогда, когда ее зависимости изменились.
В следующем примере функция вычисления будет выполняться только при изменении count
, а не при добавлении задач.
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(() => calculation(count), [count]); const increment = () => { setCount((c) => c + 1); }; const addTodo = () => { setTodos((t) => [...t, "New Todo"]); };
const calculation = (num) => { console.log("Calculating..."); for (let i = 0; i < 1000000000; i++) { num += 1; } return num; };
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>Calculation</h2> {calculation} </div> </div> ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);