1️⃣ useMemo()의 역할
useMemo()는 값을 메모이제이션하기 위해 사용되는 React Hook입니다. 이로 인해 비용이 많이 드는 계산을 불필요하게 반복하지 않도록 최적화할 수 있습니다.
이 코드에서 useMemo()의 사용 목적은 아래와 같습니다:
- 컴포넌트 리렌더링 방지
App 컴포넌트는 name 또는 num 상태값이 변경될 때마다 리렌더링됩니다.
하지만 name이 변경되더라도, num이 바뀌지 않았다면 isPrime(num)을 다시 실행할 필요가 없습니다.
👉 useMemo()를 사용하면, num이 변경되지 않은 경우 기존에 계산했던 결과를 재사용하게 됩니다. - 비용이 큰 연산의 재사용
isPrime() 함수는 주어진 숫자가 소수인지 확인하는 함수로, 숫자가 클수록 계산 비용이 커집니다.
useMemo()는 num이 변경되지 않은 경우, 이전에 계산된 결과를 반환함으로써 불필요한 계산을 방지합니다.
2️⃣ Dependency Array ([num])의 역할
useMemo(() => isPrime(num), [num])에서 의존성 배열 [num]은 다음을 의미합니다:
- num 값이 변경될 때만 isPrime(num)을 다시 실행합니다.
- 만약 num이 바뀌지 않았다면, 이전에 계산된 값을 반환합니다.
전체 동작 과정
- 초기 상태
컴포넌트가 처음 렌더링될 때 num 값은 1입니다.
useMemo()는 isPrime(1)을 실행하고, 결과(false)를 result에 저장합니다. - name이 변경될 때
사용자가 name 입력값을 바꾸더라도 num 값이 변경되지 않았다면, isPrime()은 다시 실행되지 않습니다.
👉 이전에 계산된 result 값이 그대로 사용됩니다. - num이 변경될 때
사용자가 num 값을 바꾸면, useMemo()는 isPrime(num)을 다시 실행합니다.
새로운 결과를 result에 저장하고, 컴포넌트가 업데이트됩니다.
예시 상황
- 사용자가 name을 **"Alice"**로 바꿉니다.
- isPrime()은 실행되지 않고, 기존의 result 값이 그대로 사용됩니다.
- 사용자가 num을 7로 변경합니다.
- isPrime(7)이 실행되고, 결과(true)가 result에 저장됩니다.
- 화면에 "Alice가 좋아하는 숫자 7: 소수가 맞습니다."가 표시됩니다.
useMemo()를 사용하지 않았다면?
만약 useMemo()를 사용하지 않았다면, App 컴포넌트가 리렌더링될 때마다(= name값만 변경되더라도) isPrime(num)이 항상 실행됩니다.
결과적으로 num 값이 바뀌지 않았더라도 불필요한 연산이 발생해 성능 저하를 초래할 수 있습니다.
결론
useMemo()를 사용함으로써:
- name이 변경될 때 불필요한 isPrime() 실행을 방지합니다.
- num이 변경될 때만 isPrime()을 실행해 효율적으로 컴포넌트를 업데이트합니다.
이렇게 하면 성능 최적화와 계산 비용 절감을 동시에 달성할 수 있습니다.
import { useMemo, useState } from "react";
var isPrime = function (num) {
console.time("소요 시간");
console.log("소수 판별 시작.", num);
// TODO: 소수 판별 코드
let prime = num > 1; // 1은 소수가 아니기 때문에 거름.
for (let i = 2; i < Math.sqrt(num); i++) {
if (num % i === 0) {
prime = false;
break;
}
}
console.log("소수 판별 결과.", prime);
console.timeEnd("소요 시간");
return prime;
};
function App() {
const [name, setName] = useState("GD");
const [num, setNum] = useState(1);
// 📢 useMemo(): num값이 바뀌지 않으면 다시 계산하지 않고, 메모이제이션된 함수의 리턴값을 이용
// -> 이름을 바꾸면 name이라는 상태값이 바뀌기 때문에 앱 컴포넌트 자체가 리렌더링 되어야 하는데, 이때 굳이 다시 계산하지 않음
// * num(상태값)이 바뀌면 다시 계산할 필요o => dependency : [num]
// const result = isPrime(num);
const result = useMemo(() => isPrime(num), [num]);
return (
<>
<h1>05 useMemo - 함수의 반환값을 memoize</h1>
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
가 좋아하는 숫자:
<input
type="number"
min="1"
max="1000000007"
value={num}
onChange={(e) => setNum(e.target.value)}
/>
<div>
{name}가 좋아하는 숫자 {num}: 소수가
{result ? (
<span style={{ color: "blue" }}>맞습니다.</span>
) : (
<span style={{ color: "red" }}>아닙니다.</span>
)}
</div>
</div>
</>
);
}
export default App;
'Musta React' 카테고리의 다른 글
[✍🏼 1/4 (Sat)] React.memo() 복습 (1) | 2025.01.04 |
---|---|
[✍🏼 1/4 (Sat)] Prop을 넘겨주는 방식에 따른 useMemo() 사용 여부 - 부모 컴포넌트에서 분해 or 자식 컴포넌트에서 분해 (1) | 2025.01.04 |
11/27 (Wed) 상태관리목적이 "아닌" useSearchParams()의 사용 & Pagination 로직 이해 & Context API (3) | 2024.11.27 |
11/26 (Tue) HTTP 통신과 Ajax & 리액트 라우터가 제공하는 훅 (1) | 2024.11.26 |
11/21 (Thur) ch03-hooks/05-useMemo (0) | 2024.11.22 |