useMemo
useMemo는 React에서 제공하는 Hook으로, 메모이제이션된 값을 반환합니다.
이를 통해 비용이 많이 드는 계산이 불필요하게 반복 실행되는 것을 방지할 수 있습니다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 첫 번째 인자로는 계산할 함수를 받습니다.
- 두 번째 인자로는 의존성 배열을 전달하여, 해당 배열 내 값이 변경될 때만 함수를 재실행하도록 지정합니다.
언제 사용해야 할까?
- 비용이 많이 드는 계산: 복잡한 연산을 수행하는 함수의 결과를 메모이제이션해야 할 때.
- 불필요한 렌더링 방지: 렌더링 비용이 큰 컴포넌트에서 특정 값을 재사용해야 할 때.
예제 1. 복잡한 계산 최적화
아래는 배열의 합계를 계산하는 간단한 예제입니다. 데이터가 변경되지 않았다면 계산을 다시 실행하지 않습니다.
import React, { useMemo } from "react";
type DataItem = {
id: number;
value: number;
};
const ExpensiveCalculation: React.FC<{ data: DataItem[] }> = ({ data }) => {
const total = useMemo(() => {
console.log("Calculating total...");
return data.reduce((sum, item) => sum + item.value, 0);
}, [data]);
return <div>Total: {total}</div>;
};
export default ExpensiveCalculation;
- data가 변경될 때만 합계를 다시 계산합니다.
- 이를 통해 불필요한 계산을 방지하고 성능을 최적화합니다.
예제 2.정렬된 데이터 렌더링
const SortedList: React.FC<{ items: string[] }> = ({ items }) => {
const sortedItems = useMemo(() => {
console.log("Sorting items...");
return [...items].sort();
}, [items]);
return (
<ul>
{sortedItems.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
};
export default SortedList;
- 리스트가 변경되지 않는 한 정렬 로직이 다시 실행되지 않습니다.
주의점과 한계
1. 남용을 피해야 합니다.
- useMemo는 항상 성능을 향상시키는 것은 아닙니다.
- 메모이제이션 자체에도 비용이 들기 때문에, 값비싼 계산이 아닌 경우 사용을 자제해야 합니다.
2. 의존성 배열 관리
- 의존성 배열의 값을 정확히 관리하지 않으면, 예기치 않은 동작이 발생할 수 있습니다.
- const memoizedValue = useMemo(() => computeSomething(a, b), []);
- 위 코드에서는 의존성 배열이 비어 있으므로, a와 b가 변경되어도 함수가 다시 실행되지 않습니다.
React.memo와의 차이점
React.memo와 useMemo는 모두 성능 최적화를 위한 도구이지만, 그 목적과 사용 방식이 다릅니다.
| 특징 | React.memo | useMemo |
| 목적 | 컴포넌트 전체의 재렌더링 방지 | 특정 계산 값의 재계산 방지 |
| 적용 대상 | React 컴포넌트 | 함수가 반환하는 계산된 값 |
| 작동 방식 | props가 변경되지 않으면 렌더링을 건너뜀 | 의존성 배열이 변경되지 않으면 계산을 건너뜀 |
| 사용 시점 | 컴포넌트가 자주 재렌더링될 때 | 비싼 계산이나 함수 호출이 반복될 때 |
| 예제 코드 | export default React.memo(MyComponent); | useMemo(() => computeExpensiveValue(), []); |
react.memo
import React from "react";
const MyComponent: React.FC<{ value: number }> = ({ value }) => {
console.log("Rendering MyComponent");
return <div>{value}</div>;
};
export default React.memo(MyComponent);
- props가 변경되지 않는 한 MyComponent는 다시 렌더링되지 않습니다.
usememo와 함께 사용
const ParentComponent: React.FC<{ items: number[] }> = ({ items }) => {
const sortedItems = useMemo(() => {
console.log("Sorting items...");
return [...items].sort();
}, [items]);
return <ChildComponent items={sortedItems} />;
};
const ChildComponent = React.memo(({ items }: { items: number[] }) => {
console.log("Rendering ChildComponent");
return (
<ul>
{items.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
);
});
- ParentComponent는 useMemo를 통해 정렬된 값을 메모이제이션합니다.
- ChildComponent는 React.memo를 통해 props가 변경되지 않는 한 렌더링을 건너뜁니다.
useMemo는 React에서 성능 최적화를 위해 제공되는 강력한 도구입니다.
그러나, 이를 적절히 사용하는 것이 중요합니다.
비용이 많이 드는 계산이나 렌더링이 자주 발생하는 컴포넌트에만 사용하고, 의존성 배열을 신중하게 관리해야 합니다.
React.memo와의 차이점을 이해하고 적절히 활용하면, 더욱 효율적인 React 애플리케이션을 개발할 수 있습니다.
'개발 공부 > React' 카테고리의 다른 글
| React.ReactNode, ReactElement, ComponentProps, Ref (0) | 2025.01.31 |
|---|---|
| React.FC (0) | 2025.01.30 |
| React.memo (2) (0) | 2025.01.24 |
| React.memo (1) (1) | 2025.01.22 |
| NextAuth.js 요약 (1) | 2025.01.19 |