하다보니
[React Hooks]useMemo 본문
컴포넌트 최적화를 위해 사용하는 hook - useMemo, useCallback
memo는 memoization을 뜻한다. 동일한 값을 리턴하는 함수를 반복적으로 호출해야 한다면 필요할 때마다 또다시 계산하지 않고 메모리에서 꺼내서 재사용하는 기법.
자주 필요한 값을 맨처음 계산시 캐싱을 해줘서 필요할때마다 캐시에서 꺼내서 사용한다.
함수형 컴포넌트는 말그대로 함수이고, 렌더링된다는 것은 함수가 호출된다는 뜻이다. 이것은 모든 내부 변수가 초기화된다는 말이다.
useMemo를 사용해서 메모이제이션을 해주면 불편함 개선 가능.
첫번째 인자는 콜백함수. 메모이제이션 해줄 값을 계산해서 리턴해준다. 이 콜백함수가 리턴하는 값이 useMemo가 리턴하는 값이다. 두번째 인자 배열은 의존성 배열. 해당 배열 요소값이 업데이트 될 때만 콜백함수를 호출해서 메모이제이션 된 값을 업데이트 해서 다시 메모이제이션 해준다.
useMemo를 남용하면 성능에 무리가 갈 수 있다. 값을 재활용하기 위해 따로 메모리를 소비해서 저장을 해둔다는 것이다. 따라서 꼭 필요할때만 적절하게 사용하는 것이 중요하다.
import { useMemo, useState } from "react";
const hardCalculate = (number) => {
console.log("어려운 계싼");
for (let i = 0; i < 999999999; i++) {}
return number + 10000;
};
const easyCalculate = (number) => {
console.log("짱 쉬운 계산");
return number + 1;
};
function App() {
const [hardNumber, setHardNumber] = useState(1);
const [easyNumber, setEasyNumber] = useState(1);
// easyNumber state만 바뀌어도 App 컴포넌트 자체가 리렌더링이 되어서 hardCalculate도 불리게 된다.
// const hardSum = hardCaculate(hardNumber);
// hardNumber가 바뀔때만 hardCalculate가 실행되고 아니면 hardSum을 재사용하게 된다.
// 사실은 이렇게 1초 이상 걸리는 함수로 컴포넌트 내부 변수를 초기화해주는 일은 많지 않다.
const hardSum = useMemo(() => {
return hardCalculate(hardNumber);
}, [hardNumber]);
const easySum = easyCalculate(easyNumber);
return (
<div>
<h3>어려운 계산기</h3>
<input
type="number"
value={hardNumber}
onChange={(e) => setHardNumber(parseInt(e.target.value))}
/>
<span>+10000={hardSum}</span>
{/* easySum */}
<h3>쉬운 계산기</h3>
<input
type="number"
value={easyNumber}
onChange={(e) => setEasyNumber(parseInt(e.target.value))}
/>
<span>+1={easySum}</span>
</div>
);
}
export default App;
- useMemo가 빛을 발하는 예시
객체는 메모리 상에 공간이 할당되어 그 메모리 안에 보관된다. 변수 안에는 그 객체가 담긴 메모리 주소가 보관이 된다.
import { useEffect, useMemo, useState } from "react";
function App() {
const [number, setNumber] = useState(0);
const [isKorea, setIsKorea] = useState(true);
// app 컴포넌트라 리렌더링되면 location도 새로 할당받는다. 즉, 이전과 다른 메모리상에 저장이 된다.
// const location = {
// country: isKorea ? "한국" : "외국",
// };
const location = useMemo(() => {
return {
country: isKorea ? "한국" : "외국",
};
}, [isKorea]);
// 따라서 location이 바뀌었다 인지해서 useEffect 계속 불림. 따라서 useMemo 사용.
useEffect(() => {
console.log("useEffect 호출");
}, [location]);
return (
<div>
<h2>하루에 몇끼 먹어요?</h2>
<input
type="number"
value={number}
onChange={(e) => setNumber(e.target.value)}
/>
<hr />
<h2>어느 나라에 있어요?</h2>
<p>나라:{location.country}</p>
<button onClick={() => setIsKorea(!isKorea)}>비행기 타자</button>
</div>
);
}
export default App;
'프로그래밍 언어 > React' 카테고리의 다른 글
[Next.js] 입문 (0) | 2022.07.18 |
---|---|
[React Hooks]useCallback (0) | 2022.07.12 |
[React Hooks]useContext (0) | 2022.07.06 |
[React Hooks]useRef (0) | 2022.07.06 |
[React hooks]useEffect (0) | 2022.07.06 |