초보 개발자의 성장 일기
useMemo 본문
컴포넌트를 만들고 나면 성능을 Optimization(최적화)를 해야한다.
컴포넌트 최적화를 위한 대표적인 Hooks
- useMemo
- useCallback
Memo란?
Memoization을 의미하며 동일한 값을 리턴하는 하는 함수를 반복적으로 수행해야 한다면 맨 처음 값을 계산할 때 해당값을 메모리에 저장해서 필요할때마다 다시 계산하지 않고 메모리에서 꺼내서 재사용한다. 자주 필요한 값을 처음 계산할 때 캐싱을 해 두어 값이 필요할 때 캐시에서 꺼내 사용한다.
함수형 컴포넌트
함수로 정의되어있는 컴포넌트를 의미한다.
function Component() {
const value = calculate();
return <div>{value}</div>
}
component 함수 호출 시 변수 value는 계속 초기화가 된다.
function calculate() {
return 10
}
<Component />
함수형 컴포넌트가 렌더링이 된다는 것은 함수를 호출된다는 것을 의미하고 호출될 때 모든 내부 변수가 초기화가 된다.
function Coponent() {
const value = useMemo(
() => calculate(), []
)
return <div>{ value }</div>
}
useMemo를 사용하면 처음에 계산된 값을 메모리에 저장하여 컴포넌트가 반복적으로 렌더링이 되어도 다시 호출하지 않고 이전에 이미 계산된 결과값을 메모리에서 꺼내와서 재사용 할 수 있도록 해 준다.
useMemo는 첫번째 인자로 콜백함수, 두번째 인자로 배열을 받는다. 콜백함수는 Memoization해줄 값을 계산해서 return을 해 준다. 콜백함수가 return하는 값이 useMemo가 return하는 값이 된다. 배열은 의존성 배열이라고 한다. 배열안의 요소의 값이 update될 때 만 콜백함수를 다시 호출해서 Memoization된 값을 update해서 다시 Memoization을 해 준다. 빈 배열 []을 넘겨주면 처음 컴포넌트가 mount되었을 때만 값을 계산해 주고 항상 Memoization된 값을 꺼내와서 사용한다.
하지만 무분별하게 남용하면 성능에 무리가 간다. 꼭 필요할 때만 사용해야 한다.
값을 재활용 하기 위해 메모리를 따로 소비하여 저장을 해 놓는 것이다. 불필요한 값을 모두 Memoization하면 성능이 안좋아진다.
const value = useMemo(() => {
return calculate();
}, [item]);
자바스크립트의 타입
원시(Primitive) 타입
String, Number, Boolean, Null, Undefined, BigInt, Symbol
변수에 저장할 때 변수 안에 바로 넣어진다.
다른 이름의 같은 값을 사진 두 원시 타입을 같다고 비교하면 true가 나온다.
객체(Object) 타입
원시타입을 제외한 모든 것
Object, Array
변수에 저장할 때 메모리 상에 공간이 할당돼서 메모리 안에 보관된다. 변수 안에는 객체가 담긴 메모리 주소가 담겨진다.
다른 이름의 같은 값을 가진 두 객체를 같다고 비교하면 false가 나온다. 이유는 변수 안에 메모리 주소가 담겨 있고 두 객체의 메모리 주소는 다르기 때문이다.
useEffect 의존성 배열에 객체 타입을 넣을 경우
const [isKorea, setIsKorea] = useState(true);
const location = {
country: isKorea ? '한국' : '외국',
};
useEffect(() => {
console.log('useEffect 호출');
}, [location])
<p>{location.country}</p>
다른 state가 변경될 때 원시 타입이었을 땐 찍히지 않았던 'useEffect 호출'이 객체 타입일 때 콘솔에 찍힌다.
이유는 location 객체가 다시 불러올 때 이 전에 불려진 location객체와 다른 메모리 주소를 가지고 있어 값이 다르다. useEffect안의 의존성배열 location은 다른 주소를 가지고 있어 변경이 되었다고 인식한다.
const location useMemo(() => {
return {
country: isKorea ? '한국' : '외국',
};
}, [isKorea]);
useMemo를 사용하여 해결이 가능하다.
'Development > React JS' 카테고리의 다른 글
React 테스팅 (1) | 2023.12.01 |
---|---|
useCallback (2) | 2023.12.01 |
useContext (0) | 2023.11.30 |
useRef (0) | 2023.11.30 |
useEffect (0) | 2023.11.30 |