
오늘 포스팅 할 내용은 useMemo와 useCallback 입니다 !
요즘 리팩토링을 시작하면서 성능개선에 대해서도 관심을 가지게 되었는데 이 친구들이 성능 개선에 기여를 하는 친구들이네여..
바로 포스팅으로 정리해둬야겠다 생각이 들어서 작성하게 되었습니다 🫡
다들 useState와 useCallback은 많이 사용해보셨지만, useMemo와 useCallback은 생소하게 느껴지시는 분들이 많을 것이라고 생각이 듭니다. ( 저도 마찬가지.. ㅎㅎ; )
useMemo와 useCallback은 리액트의 렌더링 성능을 최적화 하는 hook이기 때문에 필수적으로 사용할 필요는 없습니다.
그럼에도 불구하고 포스팅을 하는 이유는 할 수 있는데 안하고 있던 제 자신을 반성하기 위해서 입니다 :)
1. 메모제이션 (Memozation)
들어가기 전에 먼저 메모제이션이라는 개념에 대해 확실히 알아둬야합니다.
메모제이션이란 기존에 수행한 연산의 결과값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법입니다.
이것을 이용하면 불필요한 리렌더링을 방지할 수 있기 때문에 애플리케이션의 성능을 최적화 할 수 있습니다.
2. 리렌더링 (re-rendering)
컴포넌트는 자신의 state가 변경되거나, 부모에게서 받는 Props가 변경될 때 마다 리렌더링 됩니다.
컴포넌트가 렌더링 된다는 것은 누군가가 그 함수를 호출하여 실행되는 것을 말하며 함수가 실행될 때 마다 내부에 선언되어 있던 표현식도 매번 다시 선언되어 사용됩니다.
( 표현식이 그대로더라도 다시 호출되어 리렌더링이 된다. )
[3] useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a,b), [a,b]);
( 출처: 리엑트 공식문서 )
useMemo는 메모리제이션된 값을 반환한다. useMemo가 a,b에 의존하고 있음을 나타냅니다.아래의 예제를 한번 같이 살펴봅시다.
const Button = memo(({ text, onClick }) => {
console.log("Button", text, "re-rendering");
const result = useMemo(() => calculateSomething(), []);
return (
<button
onClick={onClick}
style={{
backgroundColor: "black",
color: "white",
borderRadius: "20px",
margin: "0.2rem",
}}
>
{`${text} ${result}`}
</button>
);
});
function calculateSomething() {
for (let i = 0; i < 10000; i++) {
console.log("😳");
}
return 10;
}
Button이라는 컴포넌트는 memo로 래핑되어있으며, 컴포넌트 내부에 useMemo를 통해 calculateSomething이라는 함수를 실행하고 있습니다. 의존성배열이 빈 것을 보면 실행될 때 한번만 실행된다는 것을 알 수 있습니다.
React.memo는 컴포넌트를 렌더링하고 결과를 메모이징합니다.
useMemo는 메모이즈 된 값을 return하는 hook 입니다.
calculateSomething 함수와 같이 컴포넌트 내에서 무거운 일을 하는 경우, useMemo를 사용하면 해당 컴포넌트가 호출될 때 마다 실행되는 것을 방지할 수 있기 때문에 성능을 향상시킬 수 있습니다.
만약 useMemo를 사용하지 않았다면 Button 컴포넌트가 호출 될 때 마다 해당 함수가 호출되는 일이 발생합니다.
🚨 useMemo를 사용하지 않은 경우
함수를 실행할 때 마다 콘솔창에는 Button 컴포넌트 내 calculateSomething함수가 계속해서 실행 될 것 입니다.
➡️ 하지만 useMemo를 사용하여 , 처음 렌더링 될때만 해당 함수를 실행하도록 해주고, Button 컴포넌트가 실행되어도 calculateSomething함수는 실행되지 않을 것 입니다.
React.memo는 HOC(Higher-Order Components) vs useMemo는 hook
(HOC: 컴포넌트를 인자로 받아 새로운 컴포넌트를 다시 return 해주는 함수)
React.memo는 HOC이기 때문에 클래스형 컴포넌트, 함수형 컴포넌트 모두 사용가능하지만, useMemo는 hook이기 때문에 오직 함수형 컴포넌트 안에서만 사용 가능하다.