useMemo
✒️ 2025-05-28 10:43 내용 수정
useMemo
리렌더링 사이의 함수 결과를 캐시할 수 있는 Hook
- 참고 자료 : React useMemo
useMemo()는 Component 최상단에서 호출하여 리렌더링 사이의 계산 결과를 캐시한다.- cache에 대한 설명은 useCallback을 참고. 한 마디로 저장해두는 것.
useCallback()과 매우 비슷하지만,useMemo()는 함수 호출 결과를 캐싱하고,useCallback()은 함수 자체를 캐싱한다는 점이 다르다.
- 이러한 특성을 이용하여
useCallback()처럼 성능 최적화에 사용할 수 있다. - Strict 모드에서 React가 의도치 않은 불순물 탐색을 위해 계산 함수를 두 번 호출하지만, 이는 개발 전용 동작으로 상용 환경에 영향을 끼치지 않는다.
- React는 특별한 이유가 있지 않는 한 캐시된 값을 유지한다.
const cachedValue = useMemo(calculateFn, dependencies);
- 첫 번째 매개변수로 캐시하려는 값을 계산하는 함수를 전달한다.
- 전달하는 함수는 순수함수여야 하며, 어떤 인자도 받지 않고 (
()=>{}), 어떤 타입의 값이든 반드시 반환해야 한다. - 초기 렌더 때 React는 전달한 함수를 호출하며, 다음 렌더 때 dependencies가 마지막 렌더 이후 바뀌지 않았다면 동일한 값을 반환한다.
- dependencies가 변경되었다면 전달했던 함수를 호출해서 그 결과를 반환하고, 다시 사용할 수 있도록 저장한다.
- 전달하는 함수는 순수함수여야 하며, 어떤 인자도 받지 않고 (
- 두 번째 매개변수는 첫 번째 매개변수였던 함수의 코드 내에서 참조되는 모든 반응형 값들의 목록을 전달한다.
useCallback()의 매개변수처럼 props, state, Component 본문 내에 선언한 모든 변수 및 함수가 포함된다.- 마찬가지로 전달할 때
[dep1, dep2, dep3, ...]처럼 인라인으로 작성해야 한다.
import { useMemo } from 'react';
function Test() {
// useMemo() 사용 시 리렌더링 사이에 result를 캐싱하도록 지시
const result = useMemo(()=>{ // useMemo에 전달하는 함수는 인자를 받지 않는다.
doMultiple(num1, num2); // 계산 함수는 어떤 타입의 값이든 반드시 반환
}, [num1, num2]); // num1과 num2가 변경되지 않는 한 useMemo()로 반환되는 값은 동일한 값이다.
}
useCallback()에서 작성했던 내용과 마찬가지로, React에서는 Component가 리렌더링 될 때마다 Component의 본문 전체를 다시 실행한다.- 대부분의 계산 함수는 계산이 매우 빨리 진행되어 큰 문제가 생기지 않는다.
- 하지만 공식 사이트에 나오는 설명대로 큰 배열을 필터링하거나, 변환, 고비용의 계산을 수행할 때 데이터가 변경되지 않았음에도 Component를 리렌더링할 때마다 계산을 매번 수행한다면 성능에 큰 영향을 끼칠 수 있다.
- 따라서 dependencies가 변하지 않았다면 이전에 계산한 결과를 재사용할 수 있도록
useMemo()를 사용하며, 이런 종류의 캐싱을 메모화(memoization) 라고 한다.
- 리렌더링마다 계산 함수가 항상 다른 결과값을 반환하고, 이는
{}객체 리터럴이 항상 새 객체를 생성하는 것과 비슷하다.- 일반적으론 문제되지 않으나,
memo를 사용하여 리렌더를 건너뛰도록 지시하는 경우 반환값을 매번 재생성하는 것은 최적화에 문제가 된다. - 특정 값을 매 리렌더링때마다 새로 생성하지 않고 dependencies가 변경되기 전까지 동일한 값을 사용하도록 하려면
useMemo()를 사용해야 한다.
- 일반적으론 문제되지 않으나,
function App() {
return(
{/* TestPage component에 num1와 num2을 전달 */}
<TestPage num1={10} num2={5}/>
)
}
export default App;
import { useMemo, memo } from 'react';
export default function TestMemoPage({num1, num2, theme='dark'}) {
// useMemo()를 사용하지 않았다면 result는 theme이 변경될 때마다 매번 계산됨
// useMemo() 사용시 리렌더링 사이에 doMultiple() 계산 결과를 캐싱하도록 지시
// 전달할 함수 내에서 호출할 함수(즉 계산할 함수)
function doMultiple(num1, num2) {
return num1 * num2;
}
const result = useMemo(()=>{// useMemo에 전달하는 함수는 인자를 받지 않는다.
return doMultiple(num1, num2);
}, [num1, num2]); // num1과 num2가 바뀌지 않는 한 result는 동일한 값을 캐싱한다.
return(
<div className={theme}>
<Test result={result}/>
</div>
)
}
// theme이 변경되더라도 result가 변경되지 않으면 리렌더링하지 않는다.
const Test = memo(function Test({ result }) {
return (
<div>계산 결과 : {result}</div>
)
})
- 모든 곳에
useMemo()를 사용하여 최적화를 실행할 필요는 없으며, 상황에 따라 state와 Effect만으로 처리할 수 있다.