const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
메모이제이션 된 값을 반환한다.
"생성(create)" 함수와 그것의 의존성 값의 배열을 전달한다. useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산한다. 이 최적화는 모든 렌더링 시의 고비용 계산을 방지하게 해준다.
useMemo로 전달된 함수는 렌더링 중에 실행된다. 통상적으로 렌더링 중에 하지 않는 것을 이 함수 내에서 해서는 안된다. 예를 들어, 사이트 이펙트(side effect)는 useEffect에서 하는 일이지 useMemo에서 하는 일이 아니다.
deps가 없는 경우 매 렌더링 때 마다 새 값을 계산하게 될 것이다.
useMemo는 성능 최적화를 위해 사용할 수는 있지만 의미상으로 보장이 있다고 생각해서는 안된다.
Hook은 useMemo 값 비싼 리소스 집약적인 기능이 불필요하게 실행되지 않도록 하는데 사용할 수 있다.
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, "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>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
성능이 좋지 않은 예이다. expensiveCalculation 함수는 모든 렌더링에서 실행된다.
useMemo를 사용하여 expensiveCalculation 함수를 메모할 수 있다. 이렇게 하면 필요할 때만 함수가 실행된다. useMemo는 종속성을 선언하기 위해 두 번째 매개변수를 허용한다. 함수는 종속성이 변경된 경우에만 실행된다. expensiveCalculation 함수는 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(() => 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>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};