우선 우리는 이것을 왜 쓰려고 하는가??
분명 리액트가 랜더링 또는 재랜더링 될 때 함수들이 똑같은 동작인데도 연산하여 성능을 잡아먹기 때문이다.
따라서 이러한 리액트 어플리케이션 성능을 최적화하기 위한 방법인 연산 결과 재사용을 알아볼 것이다.
먼저 이런 연산 결과 재사용하는 방법인 useMemo는 Memoization(메모이제이션) 기법을 적용하였다.
🧐 그렇다면 Memoization은 무엇인가?
Memoization이란?
한 번 연산해본 결과를 기억해두고, 다시 동일한 입력이 들어오면 기억해둔 데이터를 반환하는 방법이다.
- 1+1 은 무엇인가?
- (계산중...)
- (계산완료) => 2
- 다시 한번더 1+1은 무엇인가?
- (전이랑 동일하네? 기억해뒀던거 바로 반환) 2
위 방식처럼 엄청 복잡하거나 성능을 잡아먹는 함수라면 이러한 성능최적화가 필요하다.
계산을 Memoization(메모이제이션) 하는 방법은 무엇인가?
리액트 공식문서인 Hook 자주묻는 질문란에서 다음과 같은 방법을 제시하고 있다.
바로 우리가 알려고 하는 useMemo인 Hook을 사용하면 이전 계산을 기억하였다가 다시 사용할 수 있다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
이 코드는 생성(create) 함수인 computeExpensiveValue(a, b) 를 호출한다.
useMemo는 의존성인 [a, b]가 변경되었을 때에만 메모이제이션된 값만 다시 계산한다.
즉, [a, b]가 변경되지 않으면 이전결과를 바로 반환하므로 이러한 최적화는 모든 렌더링 시의 고비용 계산을 방지하게 해준다.
a와 b의 상태값이 변경되면 그것을 사용하는 모든 컴포넌트는 재렌더링 된다.
그 때 전부 렌더링이 되기에 계산도 다시하여 렌더링된다.
하지만 a와 b가 이전 값과 동일하다면 굳이 연산할 필요가 없다.
그래서 이 useMemo를 쓰는 것이다.
만약 useMemo의 두번째 인자인 의존성 값에 빈 배열이 들어간다면 매 렌더링때마다 계산을 하게 된다.
이럴 경우 useEffect와 동일하게 동작하지만 useEffect처럼 사용하면 안된다.
사이드 이펙트(side effects)는 useEffect에서 하는 일이지 useMemo에서 하는 일이 아니기 때문이다.
🧐 그래서 어떻게 쓰는거죠?
이렇게만 적으면 어떤식으로 써야할지 감을 모르시는 분들이 있을 것이다.
(저도 이론적인 부분만 알고 응용하는게 어렵더라고요...)
import { useMemo, useState } from 'react';
import './App.css';
function App() {
const [x, setX] = useState(0);
const [y, setY] = useState(0);
const getDiaryAnalysis = useMemo(() => {
console.log('useMemo 연산 시작함');
const sum = x + y;
return { sum };
}, [x, y]);
const { sum } = getDiaryAnalysis;
return (
<div className="App">
x 값 : {x}
<br />
<button onClick={() => setX(x + 1)}>x값 1 증가</button>
<br />y 값 : {y}
<br />
<button onClick={() => setY(y + 1)}>y값 1 증가</button>
<br />
{sum}
<br />
<button onClick={() => setX(1)}>x값 1로 변경하기</button>
<button onClick={() => setY(1)}>y값 1로 변경하기</button>
</div>
);
}
export default App;
그래서 간단하게 만들어보았습니다.
기본적인 리액트의 App.js 파일에서 바로 만들어서 실습하였습니다.
저렇게 실행시키면 다음과 같은 화면이 나옵니다.
여기서 x값 1증가 와 y값 1증가 버튼을 각각 2번씩 눌려보겠습니다.
x값 1증가 버튼을 2번, y값 1증가 버튼을 2번 눌렀더니 "useMemo 연산 시작함" 이 콘솔창에 4번 출력되었습니다.
따라서 저희가 코드에 적어놓은 useMemo 함수에 따라서 useMemo의 2번째 인자인 의존성 값인 [x, y] 값들이 변경되었기에 연산을 하여 값을 보내준 것 입니다.
그렇다면 이제 고정된 값을 보내보도록 하겠습니다.
x값 1로 변경하기 2번, y값 1로 변경하기 2번 눌려보겠습니다.
useMemo를 모르시는 분이라면 아까 1증가시키는 버튼을 눌렸을 때처럼 결과가 총 4번 출력될 것을 예상하셨을 겁니다.
state(상태)가 변하면 컴포넌트는 재렌더링이 되니까요.
하지만 문자는 총 2번 출력되었습니다.
왜냐하면 처음에 x와 y값을 1로 변경하였기에 2번 출력되었고,
그 후 똑같은 값으로 변경하였기에 useMemo가 동일한 입력값이 들어왔다고 판단하여 이전 결과값을 바로 반환하는 겁니다.
따라서 연산을 시작하지 않는것을 볼 수 있습니다.
'프로그래밍 > React.js' 카테고리의 다른 글
[React] React.memo란? (0) | 2022.05.28 |
---|---|
[크롬 확장프로그램]React Developer Tools 설치 (0) | 2022.05.27 |
[React]리액트에서 Redux 써보기 (0) | 2022.05.24 |