uesMemo, useCallback, React.memo

102·2022년 12월 30일
0

🫥 jsx 도 함수다!

그렇기 때문에 함수가 호출될 때마다 내부에 있는 함수들도 매번 다시 선언되어 사용된다.
이는 불필요한 메모리를 잡아먹을 수 있음!!!!!!!
컴포넌트 최적화를 위해 어떤 시도를 할 수 있을까????!??!?!?!?!!


1. useMemo

메모이제이션을 반환한다.

  • memoization : 동일한 값을 리턴하는 함수를 반복해서 호출해야 할 때 맨 처음 값을 메모리에 저장한 뒤 필요할때마다 메모리에서 꺼낸 후 재사용 하는것 이다.

기본적인 useMemo의 형태는 이러하다.
첫번째 인자로 callback 함수를 받고 두번째 인자로 배열을 받는다.

const value = useMemo(()=> {
	return calculate();
},[item]);
  • 콜백함수 : 메모이제이션 해줄 값을 계산해서 리턴해주는 함수.
  • 의존성 배열 : 배열의 요소의 값이 업데이트 될때만 콜백함수가 호출되어 메모이제이션 된 값을 업데이트 해준다.


2. useCallback

메모이제이션함수를 반환한다.

보통 이벤트 핸들러 함수나 api를 요청하는 함수를 주로 useCallback으로 많이 사용한다.
그렇지만 어려운 로직이 아니라면 굳이 사용하지 않는것을 추천한다.

함수를 props로 넘길 때 useCallback으로 쌓여지지 않은 그냥 함수를 넘긴다면
상위 컴포넌트가 재 렌더링되고 함수가 재 선언될때마다 하위컴포넌트에서 넘겨받은 함수가 달라졌다고 인식하기 때문에 함수를 props로 넘길때 사용하는것을 권장한다.


기본적인 useCallback의 형태는 이러하다.
첫번째 인자로 callback 함수를 받고 두번째 인자로 배열을 받는다.

const calculate = useCallback((num)=> {
	return num+1;
},[item]);

의존성 배열이 바뀌지 않는이상 이 calculate 함수는 재선언 되지 않는다.



3. React.memo

리액트에서 제공해주는 고차컴포넌트(Higher Order Component)
고차컴포넌트란 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다.

🚨 React.memo 는 꼭 필요할때만 사용해야한다.
렌더링 횟수 감소로 인해 이득을 볼수도 있지만 무분별하게 사용한다면 컴포넌트를 메모이징할때 렌더링된 결과를 메모리에 저장하기 때문에 꼭 필요할때만 사용해야한다.

  1. 컴포넌트가 같은 props로 자주 렌더링 될때
  2. 컴포넌트가 렌더링 될때마다 복잡한 로직을 처리해야 할때

React.mome 는 props 변화에만 의존하는 최적화 방법이다.
그렇기 때문에 useState , useReducer , useContext 같은 상태와 관련된 훅을 사용한다면 props에 변화가 없더라도 ✨ state나 context가 바뀔때마다 렌더링이 일어난다 ✨


기본적인 React.memo의 형태는 이러하다.
사용하고 싶은 하위 컴포넌트를 memo에 감싸주면 된다.

import {memo} from 'react';

const Child = ({props}) => {
	<div>{props}</div>
}

export default memo(Child);

React.memo 함수는 컴포넌트를 인자로 받아서 또 다른 (최적화된)인자로 반환해준다.
React.memo로 쌓여있는 인자는 부모 컴포넌트가 렌더링 되기전에 props check를 해서 props가 바뀌었을때만 렌더링이 일어나게 해준다.



4-1. React.memo 와 useMemo 함께 사용하는 경우

🚨 여기서 props가 object라면 계속 렌더링이 일어나게 되는데
그 이유는 javascript 에서 object는 원시타입이 아니기 때문에 object가 저장되어있는 메모리의 주소가 변수에 저장이 되어 있기 때문에 부모 component에서 렌더링이 일어나게 되면 objcet의 메모리의 주소도 변경이 되고 리액트는 이것을 값이 바뀌지 않아도 아까와 다른 object라고 인식하게 된다.

이때, useMemo를 이용하여 object 를 감싸주면 object가 담겨있는 메모리의 주소는 변하지 않게 된다.


4-2. React.memo 와 useCallback과 함께 사용하는 경우

🚨 javascript 에서 함수는 '객체'의 한 종류이다. 그렇기 때문에 함수도 메모리 주소가 저장되어 있기 때문에 부모 component에서 렌더링이 일어나게 되면 함수의 메모리 주소가 바뀌어 리액트는 자식도 재렌더링 시켜버린다.

이때, useCallback을 이용하여 함수를 감싸주면 함수가 담겨있는 메모리의 주소는 변하지 않게 된다.



⚒️ 결론

React.memo 와 useCallback , useMemo 를 잘 조합해서 쓴다면 성능 개선에 매우 도움이 되겠지만
잘못해서 사용한다면 오히려 성능 저하가 될수있으니 신중하게 사용하자!!!! 🥔

0개의 댓글