React에서 메모이제이션이란 렌더링 성능을 최적화하는 방법중 하나이다.
계산된 값을 저장해두었다 동일한 계산을 요구할 때 다시 사용하게되어 불필요한 연산을 줄일 수 있다.
하지만 계산된 값을 저장해두는 만큼, 불필요한 사용 시 메모리만 잡아먹는 상황도 생겨난다.
React에서는 useMemo, useCallback, React.memo를 통해 메모이제이션을 사용할 수 있다.
/*useMemo*/
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
/*useCallback*/
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
두 훅 모두 React에서 제공하는 자체 api 이다.
단 한가지 차이는 '값'을 반환하가, '함수'를 반환하는 가이다.
기본적으로,
첫번째 param = callback 함수
두번째 prama = 의존성 배열
공통적인 형태를 갖고있다. (직접 내부 코드를 살펴봐도 알 수 있다.)
동작은 아래와 같다.
즉, 컴포넌트 업데이트시 불필요하게 값 또는 함수를 다시 만들어내는 일을 없앨 수 있다.
/*React.memo*/
const MyComponent = React.memo(function MyComponent(props) {
/* 렌더링 로직 */
});
해당 메서드는 메모된 컴포넌트를 반환한다.
즉, 컴포넌트의 props이 바뀌지 않는 이상 불필요한 렌더링을 하지 않는 것이다.
list형식의 자식을 갖고있는 컴포넌트에 유용하게 사용될 수 있다.
만약 useMemo로 반환된 값이 prop으로 전해저 오는 상황이라면 React.memo로 감싸줘야 제대로된 효과를 볼 수 있을 것이다.
기껏 useMemo로 재계산을 피했는데, prop으로 전달받은 컴포넌트가 리렌더링되면 안되니까, React.memo를 통해 리렌더링까지 피할 수 있는 것이다.
자주 렌더링이 일어난다고 해서 가벼운 계산에도 메모이제이션을 적용하는 경우가 있다.
이는 코드 가독성을 떯어트릴 뿐더러 불필요한 메모리를 잡아먹는다.
메모이제이션을 사용하는 건 계산을 줄이기 위함인데, 의존성이 자주 바뀌면 어차피 계산은 계속 일어나기 마련이다.
--> 조사 필요
자식 컴포넌트에 계산된 값을 전달하는지, 계산 로직 자체(비용을 부담시키게 됨)를 전달하는지