📌 useMemo()
: 계산된 값을 메모이제이션하여, 종속성 배열 값이 변경되지 않는 한 불필요한 재계산을 방지하는 훅
- 값의 메모이제이션(값의 캐싱)을 통해 성능 최적화를 위해 사용
- 종속성 배열에 명시된 값이 변경되지 않는 한, 이전에 계산된 값을 재사용한다.
(React는 기본적으로 컴포넌트가 리렌더링될 때마다 모든 변수를 재계산한다.)
➡︎ 불필요한 재계산 방지
➡︎ 계산이 비싼 작업일 때, 성능 향상 - 주로 계산량이 많거나, 리렌더링 시 재계산할 필요가 없는 값을 메모이제이션(memoization)하는 데 사용
- 메모이제이션 된 컴포넌트가 불필요한 렌더링을 반복한다면, useMemo()를 사용하여 불필요한 렌더링을 줄일 수 있다.
(메모이제이션 된 컴포넌트를 렌더링 제어하는 핵심 ➡︎ 컴포넌트 속성(props))
const cachedValue = useMemo(() => {
// calculateValue 로직
}, [dependencies])
- 매개변수
- 콜백 함수(calculateValue)
: 메모이제이션할 값 계산 함수
- useMemo가 메모이제이션할 값을 반환
- 함수는 계산이 비싼 작업을 포함할 수 있다.
- 종속성 배열의 값이 변경될 때만 실행된다.
- 종속성 배열 [dependencies]
: 배열 안에 나열된 값들이 변경될 때만 매개변수로 전달된 콜백 함수가 다시 실행되도록 한다.
- 이 배열에 있는 값들은 함수의 반환 값을 결정하는 데 영향을 미치는 값들이다.
- 콜백 함수(calculateValue)
⏩ useMemo() 특징
- 불필요한 계산 방지
- useMemo는 종속성 배열에 있는 값들이 변경되지 않는 한, 동일한 결과를 캐싱하여 재사용한다.
➡︎ 계산 비용이 큰 작업의 불필요한 재실행을 방지한다.
(계산 비용이 큰 작업: 배열을 정렬하거나 필터링하는 작업, 복잡한 수학 연산 등을 수행할 때 등)
- useMemo는 종속성 배열에 있는 값들이 변경되지 않는 한, 동일한 결과를 캐싱하여 재사용한다.
- 컴포넌트 리렌더링 성능 최적화
- 컴포넌트가 리렌더링될 때, useMemo를 사용하여 계산된 값을 재사용하면 리렌더링 성능을 최적화할 수 있다.
- 자식 컴포넌트에 전달되는 값이 항상 같은 참조를 유지하도록 보장하여 불필요한 리렌더링을 줄일 수 있다.
- 참조형 데이터 메모이제이션
- 참조형 데이터(객체, 배열 등)는 기본적으로 참조가 동일하지 않으면 새로운 값을 생성한다.
➡︎ useMemo는 이러한 참조형 데이터의 메모이제이션에도 유용하다.
- 참조형 데이터(객체, 배열 등)는 기본적으로 참조가 동일하지 않으면 새로운 값을 생성한다.
- 불필요한 사용 주의
- 간단한 계산이나 상태(state)가 자주 변경되지 않는 경우에는 사용하지 않는 것이 좋다.
예제) 카운트 컴포넌트
- 카운트 증가 버튼 클릭
: count 값이 변경되며, squaredValue가 재계산된다.
- 콘솔에 "Calculating squared value..."가 출력
- 메시지 토글 버튼 클릭
: showMessage 값이 변경되어 메시지가 나타나거나 사라진다.
- count와 관련된 계산은 영향을 받지 않으며, squaredValue는 메모이제이션된 값을 그대로 유지
import React, { useMemo, useState } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
const [showMessage, setShowMessage] = useState(true);
// useMemo를 사용하여 메모이제이션된 값 계산
const squaredValue = useMemo(() => {
console.log('Calculating squared value...');
return count * count;
}, [count]); // count가 변경될 때만 재계산
return (
<div>
<p>Count: {count}</p>
<p>Squared Value: {squaredValue}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setShowMessage(!showMessage)}>Toggle Message</button>
{showMessage && <p>Message is visible!</p>}
</div>
);
}
export default ExampleComponent;
✅useMemo() vs useCallback()
- useMemo()와 useCallback() 모두 자식 컴포넌트를 최적화할 때 사용
useMemo() | useCallback() | |
목적 | 값을 메모이제이션하여 계산 성능 최적화 |
함수를 메모이제이션하여 불필요한 함수 재생성 방지 |
사용 대상 | 계산된 값 (결과) | 함수 (콜백) |
사용 | 계산이 비싼 작업의 결과를 캐싱하고 재사용할 때 |
자식 컴포넌트에 콜백 함수를 전달할 때, 참조를 일정하게 유지할 때 |
메모이제이션 대상 |
반환 값 (계산 결과) | 함수 자체 |
종속성 배열 | 종속성 배열의 값이 변경될 때만 재계산 | 종속성 배열의 값이 변경될 때만 새 함수 생성 |
- useCallback() 훅 함수는 내부적으로 useMemo() 훅을 사용한다.
function useCallback(fn, dependencies) {
return useMemo(() => fn, dependencies);
}
✅ memo() vs useMemo()
- memo()와 useMemo() 모두 성능 최적화에 사용
memo() | useMemo() | |
목적 | 컴포넌트의 불필요한 리렌더링을 방지 | 계산된 값의 불필요한 재계산을 방지 |
사용 시기 | 리렌더링이 자주 발생하지만, props가 변경되지 않는 컴포넌트의 경우 |
복잡한 계산이나, 값이 변할 때만 재계산이 필요한 경우 |
적용 대상 | 컴포넌트 자체를 메모이제이션 | 값의 계산을 메모이제이션 |
사용 방식 | 고차 컴포넌트로, 컴포넌트를 감싸서 사용 | 훅으로, 컴포넌트 내부에서 사용 |
매개변수 | 1. 컴포넌트(자식 컴포넌트) 2. 비교 함수(선택) |
1. 값 계산 함수 2. 종속성 배열 |
컴포넌트 렌더링 |
props가 변경되지 않으면 컴포넌트 리렌더링 방지 |
종속성 배열의 값이 변경되지 않으면 값 계산 방지 |
useMemo – React
The library for web and native user interfaces
ko.react.dev
useCallback – React
The library for web and native user interfaces
ko.react.dev