내일배움캠프 LGLG!
6주차(주특기 숙련 - React)
useMemo
useMemo는 컴포넌트의 성능을 최적화시킬 수 있는 대표적인 react hooks 중 하나
useMemo에서 Memo는 memoization을 뜻함
memoization이란 기존에 수행한 연산의 결괏값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기업을 말한다.
useMemo를 사용하면 렌더링 -> Component 함수 호출 -> Memoize된 함수를 재사용하는 동작 순서를 거친다.
useMemo를 사용해서 memoization을 해주면 calculate 함수를 반복적으로 실행할 필요가 없다.
useMemo는 처음에 계산된 결과값을 메모리에 저장해서 컴포넌트가 반복적으로 렌더링이 되어도 계속 calculate를 다시 호출하지 않고 이전에 이미 계산된 결과 값을 메모리에서 꺼내와서 재사용할 수 있게 해준다.
useMemo는 첫 번째 인사로 콜백 함수를, 두 번째 인자로 의존성 배열을 받는다.
두 번째 인자인 배열의 요소 값이 업데이트 될 때만 콜백 함수를 다시 호출해서 memoization 된 값을 업데이트 해줘서 다시 memoization을 해준다.
만약 빈 배열([])을 넘겨주면 맨 처음 마운트 되었을 때만 값을 계산하고 이후에는 항상 memoization된 값을 꺼내와 사용한다.
1
2
3
4
5
// 첫 번째 인자 콜백함수
// 두 번째 인자 의존성배열
const value = useMemo(() => {
return calculate();
},[item])
* 꼭 필요할 때만 사용
값을 재활용하기 위해 따로 메모리를 소비해서 저장을 해놓는 것
그렇기에 불필요한 값을 모두 Memoization 해버리면 성능이 안 좋아질 수 있기 때문에 필요할 때만 사용해야 한다.
- import react Hooks의 useMemo를 사용하기 위해 react에서 useMemo를 import 받아야 한다.
1
import { useMemo } from 'react';
예제
object는 객체 타입이어서 일반 원시 타입과는 다르게 값이 저장될 때 주소 값으로 저장된다.
즉, 메모리 상의 주소가 다르게 저장되어 있는 것이다.
const location = { country: isKorea ? ‘한국’:’일본’}; 눈으로 보기에는 똑같지만 저장된 메모리 상의 주소가 완전히 다르기 때문에 useEffect의 location은 변경되었다고 생각할 수 있다.
1
2
3
4
5
const location = { country: isKorea ? '한국' : '일본' };
useEffect(() => {
console.log('useEffect... 호출');
}, [location])
따라서 이것을 해결해주려면 useMemo를 아래와 같이 사용해서 memoization 해주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { useMemo, useEffect, useState } from 'react';
function App() {
const [number, setNumber] = useState(0);
const [isKorea, setIsKorea] = useState(true);
// const location = { country: isKorea ? '한국' : '일본' };
const location = useMemo(() => {
return {
country: isKorea ? '한국' : '일본'
}
}, [isKorea])
useEffect(() => {
console.log('useEffect... 호출');
// 뭔가 오래 걸리는 작업
}, [location])
return (
<header className="App-header">
<h2>하루에 몇 끼 먹어요?</h2>
<input type="number" value={number} onChange={(e) => setNumber(e.target.value)}/>
<hr/>
<h2>어느 나라에 있어요?</h2>
<p>나라: {location.country}</p>
<button onClick={() => setIsKorea(!isKorea)}>Update</button>
</header>
);
}
export default App;