useMemo ํบ์๋ณด๊ธฐ! ๐ก๏ธ
React์์ ์ฑ๋ฅ ์ต์ ํ๋ ํ์์ ์ด์ฃ . ์ปดํฌ๋ํธ๊ฐ ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง๋๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ณ , ๋ฌด๊ฑฐ์ด ๊ณ์ฐ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด React๋ useMemo๋ผ๋ ํ๋ฅญํ Hook์ ์ ๊ณตํฉ๋๋ค. ์ค๋์ useMemo์ ์๋ ์๋ฆฌ, ์ฌ์ฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์ค์ ํ์ฉ๊น์ง ๋ชจ๋ ๊ฒ์ ์์ธํ ๋ค๋ค๋ณผ๊ฒ์.
useMemo๋? ๐ค
useMemo๋ React Hook ์ค ํ๋๋ก, ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ (Memoization)ํ์ฌ ๋ถํ์ํ ์ฌ๊ณ์ฐ์ ๋ฐฉ์งํฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ๋ ํน์ ๊ฐ์ด ๋ณํ์ง ์์๋ค๋ฉด, ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ์ฌ์ฌ์ฉํด ์ฑ๋ฅ์ ์ต์ ํํ ์ ์์ด์.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- computeExpensiveValue: ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ณ์ฐ ๋ก์ง
- [a, b]: ์์กด์ฑ ๋ฐฐ์ด. ๊ฐ์ด ๋ณํ ๋๋ง ๊ณ์ฐ ์ํ
- memoizedValue: ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๊ฐ
์ธ์ useMemo๋ฅผ ์ฌ์ฉํ ๊น์?
- ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ณ์ฐ: ๋ณต์กํ ์ฐ์ฐ(์: ๋๊ท๋ชจ ๋ฐ์ดํฐ ํํฐ๋ง, ๋ณต์กํ ์ํ ๊ณ์ฐ ๋ฑ)์ด ์์ ๋
- ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง: ๋์ผํ ๊ฐ์ด ๊ณ์ ๊ณ์ฐ๋๋ ์ํฉ์์
- ์ฑ๋ฅ ์ต์ ํ: ๋ฆฌ๋ ๋๋ง ์๋ง๋ค ๋ถํ์ํ ์์ ์ด ์คํ๋์ง ์๋๋ก
์ฃผ์: useMemo๋ ์ฑ๋ฅ ์ต์ ํ ๋๊ตฌ์ผ ๋ฟ, ๋จ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ถํ์ํ๊ฒ ๋ณต์กํด์ง ์ ์์ต๋๋ค. ์ฑ๋ฅ ๋ณ๋ชฉ์ด ์ค์ ๋ก ๋ฐ์ํ๋ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ์ธ์.
useMemo์ ๋ฌธ๋ฒ ๐ ๏ธ
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- useMemo์ ๋งค๊ฐ๋ณ์
- ์ฒซ ๋ฒ์งธ ์ธ์: ๊ณ์ฐ ๋ก์ง์ ๋ด๊ณ ์๋ ์ฝ๋ฐฑ ํจ์
- ๋ ๋ฒ์งธ ์ธ์: ์์กด์ฑ ๋ฐฐ์ด(๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์ฝ๋ฐฑ ํจ์ ์ฌ์คํ)
- ๋ฆฌํด๊ฐ
- useMemo๋ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ฉฐ, ์์กด์ฑ ๋ฐฐ์ด์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด ์ด์ ๊ฐ์ ์ฌ์ฌ์ฉํฉ๋๋ค.
useMemo ๊ธฐ๋ณธ ์์ ๐ฑ
๊ณ์ฐ ๊ฒฐ๊ณผ ๋ฉ๋ชจ์ด์ ์ด์
import React, { useMemo, useState } from "react";
function ExpensiveCalculation({ number }) {
const computeFactorial = (n) => {
console.log("Calculating factorial...");
if (n === 0) return 1;
return n * computeFactorial(n - 1);
};
const factorial = useMemo(() => computeFactorial(number), [number]);
return (
<div>
<h2>Factorial of {number}: {factorial}</h2>
</div>
);
}
export default function App() {
const [number, setNumber] = useState(5);
const [counter, setCounter] = useState(0);
return (
<div>
<ExpensiveCalculation number={number} />
<button onClick={() => setNumber(number + 1)}>Increment Number</button>
<button onClick={() => setCounter(counter + 1)}>Increment Counter</button>
<p>Counter: {counter}</p>
</div>
);
}
๊ฒฐ๊ณผ
- number๊ฐ ๋ณํ ๋๋ง ๊ณ์ฐ:
- number๊ฐ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด “Calculating factorial…” ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋์ง ์์ต๋๋ค.
- ๋ถํ์ํ ์ฌ๊ณ์ฐ ๋ฐฉ์ง:
- counter๊ฐ ๋ณ๊ฒฝ๋๋๋ผ๋ factorial์ ์ฌ๊ณ์ฐ๋์ง ์์์.
์ค์ ํ์ฉ ์ฌ๋ก ๐ผ
๋๊ท๋ชจ ๋ฐ์ดํฐ ํํฐ๋ง
import React, { useMemo, useState } from "react";
function FilteredList({ items, searchTerm }) {
const filteredItems = useMemo(() => {
console.log("Filtering items...");
return items.filter((item) =>
item.toLowerCase().includes(searchTerm.toLowerCase())
);
}, [items, searchTerm]);
return (
<ul>
{filteredItems.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
export default function App() {
const [searchTerm, setSearchTerm] = useState("");
const items = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];
return (
<div>
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
/>
<FilteredList items={items} searchTerm={searchTerm} />
</div>
);
}
ํต์ฌ ํฌ์ธํธ
- ๊ฒ์์ด๋ฅผ ์ ๋ ฅํ ๋๋ง ํํฐ๋ง ํจ์ ์คํ
- useMemo ์์ด ์์ฑํ๋ค๋ฉด ์ ๋ ฅ๊ฐ ๋ณํ์ ๋ฌด๊ดํ๊ฒ ๋งค๋ฒ ํํฐ๋ง์ด ์คํ๋์ ๊ฒ๋๋ค.
useMemo vs React.memo ๐๏ธ
๋์ ์ข ์ข ํผ๋๋์ง๋ง ๋ชฉ์ ๊ณผ ์ญํ ์ด ๋ค๋ฆ ๋๋ค.
ํน์ง | useMemo | React.memo |
์ญํ | ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ | ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ |
์ฌ์ฉ ๋์ | ํจ์ ๋ด๋ถ์์ ์คํ๋๋ ๊ฐ | React ์ปดํฌ๋ํธ |
์์กด์ฑ ๊ด๋ฆฌ | ์์กด์ฑ ๋ฐฐ์ด๋ก ํน์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง ์ฌ๊ณ์ฐ | props๊ฐ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง |
์ฃผ์์ฌํญ ๐จ
- ๋ถํ์ํ ์ฌ์ฉ ์์ :
- ๊ฐ๋จํ ๊ณ์ฐ์๋ ์คํ๋ ค ์ฑ๋ฅ์ ์ ํ์ํฌ ์ ์์ต๋๋ค. ๋ณต์กํ ์ฐ์ฐ์์๋ง ์ฌ์ฉํ์ธ์.
- ์์กด์ฑ ๋ฐฐ์ด ์ ํํ ๊ด๋ฆฌ:
- ์์กด์ฑ์ ๋น ๋จ๋ฆฌ๋ฉด, ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๊ฐ์ด ์๋ชป๋ ์ํ๋ฅผ ์ ์งํ ์ ์์ด์.
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ:
- ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ถ๊ฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์์์ ์๋นํ๋ฏ๋ก, ๋จ์ฉํ์ง ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.
useMemo๋ก ๋ฐฐ์ด ๋ชจ๋ ๊ฒ ์ ๋ฆฌ ๐ง
- ๋ถํ์ํ ๊ณ์ฐ ๋ฐฉ์ง:
- ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง ์ ์์กด์ฑ์ด ๋ณํ์ง ์์๋ค๋ฉด ์ด์ ๊ฐ์ ์ฌ์ฌ์ฉ
- ๋ฆฌ๋ ๋๋ง ์ต์ ํ:
- ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ, ๋ณต์กํ ์ฐ์ฐ, ๋ฌด๊ฑฐ์ด ๋ก์ง ๋ฑ์์ ์ฑ๋ฅ ํฅ์
- ๋จ์ํ ์์
์๋ ์ฌ์ฉํ์ง ๋ง๊ธฐ:
- ๋จ์ํ ์ฐ์ฐ์ ์ ์ฉํ๋ฉด ์คํ๋ ค ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์์ด์.
- React.memo์ ๋น๊ต:
- useMemo๋ ๊ณ์ฐ๋ ๊ฐ์, React.memo๋ ์ปดํฌ๋ํธ ์์ฒด๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
useMemo๋ ์ ์ฌ์ ์์ ์ฌ์ฉํ๋ฉด React ์ฑ์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ํ์ง๋ง ๋ชจ๋ ๊ณณ์ ์ฌ์ฉํ๋ ๋ง๋ฅ ํด๊ฒฐ์ฑ ์ ์๋์์. ๋ฌธ์ ๋ฅผ ์ ํํ ํ์ ํ๊ณ ํ์ํ ๊ณณ์ ์๋ง๊ฒ ํ์ฉํ์ธ์. ๊ทธ๋ผ ์ฌ๋ฌ๋ถ์ ์ฑ์ ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ๋์ํ ๊ฑฐ์์!
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น! ๐ท
'Front-end > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] useReducer: ์ํ ๊ด๋ฆฌ์ ์๋ก์ด ์ฐจ์! ๐๏ธ (0) | 2024.12.10 |
---|---|
[React] useEffect: ๋ผ์ดํ ์ฌ์ดํด ๊ด๋ฆฌ์ ๐ฎ (2) | 2024.12.09 |
[React] Hooks: ์ด๋ณด๋ถํฐ ์ ๋ฌธ๊ฐ๊น์ง ์๋ฒฝ ์ ๋ณต ๐ช (1) | 2024.12.07 |
[React] render() ํจ์ ์๋ฒฝ ๊ฐ์ด๋ โจ (0) | 2024.12.06 |
[React] React.StrictMode: ๊น์ด ์๊ณ ์์ฐฌ ์๋ฒฝ ๊ฐ์ด๋ ๐ (2) | 2024.12.05 |