React 컴포넌트가 한 화면에 렌더링 되는게 많아지면 최종 렌더링 시간이 오래 걸리고 ,
보여주고 싶은 정보가 많고 , 구조가 복잡할수록 렌더링 할 컴포넌트는 많아진다.
이때 효과적으로 렌더링 할 수 있게 해주는 react Hooks들이 있다.
useMemo에서Memo라는 건 Memoization을 축약한 Memo라는 뜻이다.
Memoization, 메모이제이션이란 컴퓨터 프로그램이 동일한 연산을 반복해야 할 때 기존에 연산했던 값을 메모리에 저장해 둬서 동일한 계산의 반복 수행을 없애 효율적으로 동작할 수 있게끔 하여 실행 속도를 높이는 기술이다.
리액트에서는 useMemo hook을 사용해서 이전에 연산한 값을 재사용하는 메모이제이션
기술을 적용할 수 있다.
useMemo는 메모이제이션된 값을 반환한다. 함수에 useMemo를 사용한 경우
함수 호출 부분을 값처럼 사용하여야 오류가 발생안한다.
사용 방법
<script>
const realRate = getComma(rate)
// useMemo 적용
const realRate = useMemo(() => getComma(rate), [rate])
</script>
useMemo로 사용하고자 하는 함수를 감싸서 작성한다.
두 번째 인자는 useEffect의 의존성 배열과 비슷한 맥락으로 배열에 함수의 의존성 값을 넣어 사용한다.
의존성 배열에 있는 값이 변경되었을 경우에만 값을 다시 계산하는 방식이다.
useCallback은 useMemo와는 약간 다르게 메모이제이션된 콜백을 반환한다.
useMemo는 값을 연산할 때 사용한다면 useCallback은 메모이제이션을 함수에 적용하고 싶을 때 사용한다.
<script>
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
</script>
useCallback은 보통 이벤트 핸들러 함수나 API를 요청하는 함수를 작성할 때 주로 사용된다.
useCallback은 하위 컴포넌트가 React.memo() 같은 것으로 최적화되어 있고, 그 하위 컴포넌트에게 callback 함수를 props로 넘길 때 상위 컴포넌트에서 useCallback으로 함수를 선언하는 것이 유용하다.
컴포넌트가 React.memo()로 래핑 될 때, React는 컴퍼넌트를 렌더링하고 결과를 메모이징한다. 그리고 다음 렌더링이 일어날 때 props가 같다면, React는 메모이징된 내용을 재사용한다.
React.memo와 useCallback
리렌더를 할 때 마다 부모 함수가 다른 콜백 함수의 인스턴스를 넘길 가능성이 있기 때문에
함수의 동등성 때문에, 메모이제이션을 적용할 때는 콜백을 받는 컴포넌트 관리에 주의해야한다.
즉 동일한 props 값을 전달하더라도 새로운 콜백 때문에 리렌더링을 하게 되는 경우가 발생한다. 이러한 문제를 해결하기 위해 새로운 콜백이 발생하지 않게 useCallback()을 사용해서 콜백 인스턴스를 보존시켜준다.
그렇기 때문에 React.memo() 함수를 사용하는 것이 효과적이라고 판단할 때 콜백 함수에도 신경을 써야 한다.