메모이제이션이란 계산된 값을 자료구조에 저장하고 이후 같은 계산을 반복하지 않고 자료구조에서 꺼내 재사용하는 것을 말한다. 메모이제이션의 대표적인 예로는 동적계획법의 탑다운 방식이 있다.
1. 기본 개념
-
useMemo와 useCallback는 메모이제이션 기능을 지원하는 리액트의 내장 훅으로, 퍼포먼스 최적화를 위하여 사용된다.
-
useMemo는 메모이제이션된 값을 반환한다.
-
useCallback은 메모이제이션된 콜백을 반환한다.
리액트는 실제로는 상태가 변경되는 컴포넌트와 그 이하의 모든 자식 컴포넌트가 랜더링의 대상이 된다. 문제는 자식 컴포넌트의 상태가 변경되지 않아도(갱신될 필요가 없어도) 불필요한 랜더링이 일어난다는 것이다. 자바스크립트에서 함수도 참조형 데이터이기 때문에 늘 새로운 값으로 취급되어 동일성을 보장받지 못하므로 리액트에서 매번 새로운 렌더링 대상이 된다.
2. useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
“생성(create)” 함수와 그것의 의존성 값의 배열을 전달해야 한다.useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산할 것이다. 이 최적화는 모든 렌더링 시의 고비용 계산을 방지하게 해 준다.
-
배열이 없는 경우 매 렌더링 때마다 새 값을 계산하게 된다.
-
useMemo로 전달된 함수는 렌더링 중에 실행된다.
-
무분별하게 useMemo를 사용하면 오히려 성능이 저하될 수 있다. 따라서 최대한 사용하지 않고 useEffect Hook 등을 활용해 비동기적으로 동작하도록 고안하는 것이 좋다. (리액트 공식 문서에서 추천하는 방식)
3. useCallback
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
콜백과 그것의 의존성 값을 배열로 만들어 인자로 전달하며, 메모이제이션된 콜백함수를 반환한다. 그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경된다. 이것은, 불필요한 렌더링을 방지하기 위해(예로 shouldComponentUpdate를 사용하여) 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용하다.
-
useCallback(fn, deps)은 useMemo(() => fn, deps)와 같다고 한다.
-
useEffect와 마찬가지로 두 번째 인자로 빈 배열([])을 넣으면 어떤 상태 값에도 반응하지 않으며, 두 번째 인자로 아무것도 넣지 않으면 모든 상태 변화에 반응한다.
'JavaScript > React' 카테고리의 다른 글
[React] 01. 리액트란 무엇인가? (0) | 2022.01.24 |
---|---|
[React] react-testing-library 사용법 및 기본 개념 (0) | 2021.07.10 |
[React] Class Component vs Function Component (0) | 2020.12.03 |
[React] 이벤트 처리하기 (0) | 2020.12.01 |
[React] State 다루기 (0) | 2020.11.30 |