리액트에서 함수형 컴포넌트가 작성되면 항상 랜더링 될 때마다 호출이 일어난다. 그럼 컴포넌트 안의 자바스크립트 로직들이 수행되고, 이를 기반으로 JSX로 작성된 UI가 리턴된다.
컴포넌트의 렌더링은 크게 4가지의 조건에 의해 일어난다.
function MyComponent({x, y}) {
const z = compute(x, y);
return <div>{z}</div>
}
이 컴포넌트가 렌더링될 때 재호출되는 자바스크립트 함수 compute가 만약 연산 과정이 굉장히 복잡하고 오래 걸리는 함수라 하자. 그럼 이 컴포넌트가 리렌더링될 때마다 계속해서 연산을 수행하여야 하므로 UI에서의 지연이 계속해서 일어나게 될 것이다.
따라서 만약 해당 연산에 인자로 들어오는 x와 y의 값이 항상 바뀌는 것이 아니라면, 굳이 재연산을 하여 지연 시간을 늦출 필요가 없다. x와 y의 값이 바뀌지 않는다면 z의 값을 어딘가에 저장해놓고 그 값을 다리 불러오면 된다. 이 때 useMemo를 사용하여 이 값을 메모이제이션 할 수 있다.
첫 번째 인자는 결과값을 생성해주는 함수. 즉, 위의 예시에서는 compute() 함수를 호출하는 함수를 만들어주면 된다. 두 번째 인자는 인자로 들어오는 값들의 배열이다. 이 배열을 통해서 기존의 값과 다른지 여부를 판단하여, 메모이제이션 했던 값을 불러올지 아니면 재연산을 할 지를 판단한다.
function MyComponent ({x, y}) {
const z = useMemo(() => compute(x, y), [x, y]);
return <div>{z}</div>
}
useMemo
가 적용된 레퍼런스는 재활용을 위해서 가바지 컬렉션(garbage collection)에서 제외되기 때문에 메모리를 더 쓰게 된다.