useMemo
의 memo는 memoization을 뜻합니다.
메모이제이션(memoization)은 컴퓨터프로그램이 동일한 계산을 반복할 때, 이전에 계산한 값을 메모리에 저장하여 꺼내쓰면서 반복 수행을 제거하는 것을 뜻합니다. 이를 통해 프로그램 실행속도를 빠르게 하는 것입니다.
함수형 컴포넌트에서 중복된(필요없는) 렌더링을 방지하기 위해 필요하다.
함수형 컴포넌트의 state가 변경되면, 해당 컴포넌트와 그 자식 컴포넌트들의 렌더링이 업데이트됩니다. 예시를 봅시다!
import React, { useMemo, useState } from "react";
const calculate1 = () => {
console.log("계산1");
for (let i = 0; i < 999999999; i++) {}
return 10000;
};
function Example3() {
const [value1, setValue1] = useState(0);
return (
<div>
<input type="number" value={value1} onChange={(e) => setValue1(parseInt(e.target.value))} />
<div>{calculate1()}</div>
</div>
);
}
export default Example3;
input
의 버튼을 누르면 value1
의 state가 바뀌고 콘솔로그에 "계산1"이 찍히는 것을 볼 수 있습니다.
하지만 value1
과 calculate1
은 서로 영향을 주는 코드가 아닙니다. 단지 state가 변경되었기 때문에, 해당 컴포넌트를 새로 렌더링하게 됩니다. 그로인해 "계산1"이 찍히는 것이구요.
React는 Virtual DOM은 트리구조이고 state가 업데이트되면 해당 컴포넌트 뿐만 아닌 자식 컴포넌트도 함께 업데이트됩니다. useMemo
와 react.memo
를 사용하여 이 문제를 해결할 수 있습니다.
아래의 예제코드를 통해, 컴포넌트 렌더링 문제를 useMemo
훅을 사용하여 해결할 수 있습니다.
import React, { useMemo, useState } from "react";
const calculate1 = () => {
console.log("계산1");
for (let i = 0; i < 999999999; i++) {}
return 10000;
};
function Example3() {
const [value1, setValue1] = useState(0);
const result1 = useMemo(() => calculate1(), []);
return (
<div>
<input type="number" value={value1} onChange={(e) => setValue1(parseInt(e.target.value))} />
<div>{result1}</div>
</div>
);
}
export default Example3;
이젠 "계산1"이 한번만 찍힙니다.
이처럼 useMemo
hook을 사용하여 재 계산을 방지할 수 있습니다.
만약 하위의 컴포넌트의 재렌더링을 방지하고 싶으면React.memo
를 사용할 수 있습니다. 이에 관련된 내용은 아래의 유튜브에 잘 설명되어 있습니다.
https://www.youtube.com/watch?v=oqUgcxwrnSY&t=238s