๐ก ์ง๋ ์ฃผ์ Virtual Dom๊ณผ ํจ๊ป ๋ ๋๋ง, Props, State์ ๋ํด ์์๋ดค์๋ค. => ๐๋งํฌ
์ด๋ฒ์๋ ๋ฆฌ์ํธ์ ์ฌ๋ ๋๋ง ์กฐ๊ฑด & ๋ ๋๋ง ์ฑ๋ฅ ์ต์ ํ์ ๋ํด์ ๋ค๋ฃจ๊ณ ์ ํ๋ค.
์ฌ๋ ๋๋ง ์กฐ๊ฑด์ ์์์ผ DOM์์ ๊ฐ์ฅ ๋น์ผ ์์ ์ธ Painting ๊ณผ์ ์ ์ค์ด๋, ์ฆ, ๋ ๋๋ง ์ต์ ํ์ ์ ๊ฒฝ์ ์ธ ์ ์๊ธฐ ๋๋ฌธ์ ์งง์ง๋ง ์๊ณ ์์ด์ผ ํ๋ ์ค์ํ ๊ฐ๋ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
1. ๋ฆฌ์กํธ ์ฌ๋ ๋๋ง ์กฐ๊ฑด
- State (์ํ) ๋ณ๊ฒฝ์ด ์์ ๋
- ์๋ก์ด props๊ฐ ๋ค์ด์ฌ ๋
- ๊ธฐ์กด props๊ฐ ์
๋ฐ์ดํธ ๋์ ๋
- ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ๋ฐ์ props์ ์ฐธ์กฐ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ๊ทธ props ๋ฅผ ๋ฐ๊ณ ์๋ ์์ ์ปดํฌ๋ํธ๋ ์ฌ๋ ๋๋ง ๋๋ค.
- ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ ๋๋ง ๋ ๋
- ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ ๋๋ง ๋๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ์ํด์๋ ์์ ์ปดํฌ๋ํธ๋ค๋ ์ ๋ถ! ์ฌ๋ ๋๋ง ๋๋ค.
์ฌ๋ ๋๋ง ์กฐ๊ฑด์ ์๊ฐ๋ณด๋ค ๊ฐ๋จํ๋ค!
๊ทธ๋ผ ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํ ํ ์ ์๋ ๋ฐฉ๋ฒ ๋ช ๊ฐ์ง๋ฅผ ์์๋ณด๋๋ก ํ์.
2. React Hooks - ๋ฆฌ์กํธ ๋ ๋๋ง ์ฑ๋ฅ ์ต์ ํ (React.memo, useCallback, useMemo)
์ต์ ํ๐คโ
๋ฆฌ์กํธ์์ ๋ ๋๋ง์ด ๋น๋ฒํ๊ฒ ์์ฃผ ์ผ์ด๋๋ค๋ ๊ฒ์ ์ข์ ๊ฒ์ด ์๋. ๋น์ฉ(cost)์ด ๋ฐ์ํ๋ ๊ฒ์ ์ต๋ํ ์ค์ฌ์ ํ๋ค.
์ด๋ฌํ ์์
์ ์ต์ ํ(optimization)์ด๋ผ๊ณ ํ๋ค. ๋ฆฌ์กํธ์์ ๋ถํ์ํ ๋ ๋๋ง์ด ๋ฐ์ํ์ง ์๋๋ก ์ต์ ํํ๋ ๋ํ์ ์ธ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ ํ
์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
- memo(React.memo) : ์ปดํฌ๋ํธ๋ฅผ ์บ์ฑ
- useCallback : ํจ์๋ฅผ ์บ์ฑ
- useMemo : ๊ฐ์ ์บ์ฑ
2-1. memo (React.memo)
import { memo } from "react";
React.memo()
๋ ๊ฐ์ง ๋ฐฉ์์ด ์๋ค ๊ธฐํธ์ ๋ง๊ฒ ์ฐ๋ฉด ๋๋ค.
์์์ ์ธ๊ธํ ๋ฆฌ ๋ ๋๋ง์ ๋ฐ์ ์กฐ๊ฑด ์ค 4๋ฒ ์ผ์ด์ค(๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ-๋ ๋๋ง ๋ ๊ฒฝ์ฐ ์์ ์ปดํฌ๋ํธ๋ ๋ชจ๋~ ๋ฆฌ-๋ ๋๋ง ๋จ.)๋ฅผ ๊ทน๋ณตํ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค.
ํํ
export default React.memo(๋ฉ๋ชจํ ์ปดํฌ๋ํธ๋ช
);
React.memo ์ฝ๋ ๋งํฌ ์ฒจ๋ถ
๊ธฐ์กด ๋ฌธ์ ์
๋ฌธ์ ์ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด๊ธฐ ์ํด ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ด ์๋ค๊ณ ๊ฐ์ ํ์.

๊ธฐ์กด์ ๋ฌธ์ ๋ ' + ' ๋ ' - ' ๋ฒํผ์ ๋๋ ์ ๋ ๋ชจ๋ ํ์ ์ปดํฌ๋ํธ ๋ฐ์ค๋ค๊น์ง ๋ค์ ๊ทธ๋ ค์ง๊ฒ ๋๋ค๋ ๊ฒ์ด๋ค.
๋ฐ์ ์ฌ์ง๊ณผ ๊ฐ์ด ๋ถํ์ํ ๋ ๋๋ง์ด ๋ฐ์ํ๋ค๋ ๊ฒ์ด๋ค.

์์๋ ์ฝ์์ ์ฐ๋ ๊ฒ์ผ๋ก ์์๋ฅผ ๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ: meme๋ฅผ ํตํด ํด๊ฒฐํด๋ณด๊ธฐ
- React.memo๋ฅผ ์ด์ฉํด์ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ(*๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด๋๋ ๊ฒ์ ์บ์ฑ์ด๋ผ๊ณ ํ๋ค.)ํด๋๊ณ ํ์ํ ๋ ๊ฐ๋ค ์ฐ๋ฉด ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ์ state์ ๋ณ๊ฒฝ์ผ๋ก ์ธํด props๊ฐ ๋ณ๊ฒฝ์ด ์ผ์ด๋์ง ์๋ ํ ์ปดํฌ๋ํธ๋ ๋ฆฌ๋ ๋๋ง ๋์ง ์๋๋ค. ์ด๊ฒ์ โญ ์ปดํฌ๋ํธ memoization ์ด๋ผ๊ณ ํ๋ค.
โ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ ์ปดํฌ๋ํธ๋ค์ export ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค. React.memo() ๋ก ๊ฐ์ธ์ค๋ค.
[Box1] ๋ง ์์๋ก ๊ฐ์ ธ์์
Box 1, 2, 3 ์ ๋ถ ํด ์ค์ผ ํจ.
import React from "react";
import styled from "styled-components";
const StBox = styled.div`
width: 100px;
height: 100px;
background-color: #01c49f;
color: white;
`;
function Box1() {
console.log("Box1 ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋์์ต๋๋ค!");
return <StBox>Box1</StBox>;
}
export default React.memo(Box1);
[ ๊ฒฐ๊ณผ ]

๋งจ ์ฒ์๋ง ์ ์ธํ๊ณ ์ดํ์๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ state๊ฐ ๋ฐ๋์ด๋ ๋ ๋๋ง์ด ๋์ง ์๋ ๊ฒ์ ์ ์ ์๋ค.
2-2. useCallback
useCallback์ props๊ฐ ์ ๋ฌ๋์์ ๋ ๋ถํ์ํ ๋ ๋๋ง์ ๋ง๋๋ค.
๋ฌธ์ ์ ์ฝ๋๋ค์ ๋ณด๋ฉด์ ์ดํดํ์.
ํํ
useCallback(()=>์ ์ฅํ ํจ์, [์์กด์ฑ ๋ฐฐ์ด๊ฐ])
๋ฌธ์ 1
๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ด๊ธฐํ๋ฅผ ํ ์ ํจ์๋ฅผ prop์ผ๋ก ๋ฐ์ ์์ ์ปดํฌ๋ํธ๋ ๋ค์ ๋ ๋๋ง์ด ๋๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์๋ค.
์์ ์ปดํฌ๋ํธ์ ๋ ๋๋ง์ ๋ง๊ณ ์ถ๋ค.
๋ฌธ์ ์ ์ฝ๋๋ฅผ ๋จผ์ ๋ณด์. ์์ React.memo์ ์ฝ๋๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ์์ ์ฐ๊ณ ์๋ค.
[ app.jsx(๋ถ๋ชจ ์ปดํฌ๋ํธ)์ ์ผ๋ถ ์ฝ๋ ]
const initCount = () => {
setCount(0);
};
return (
<>
<h3>์นด์ดํธ ์์ ์
๋๋ค!</h3>
<p>ํ์ฌ ์นด์ดํธ: {count}</p>
<button onClick={onPlusButtonClickHandler}>+</button>
<button onClick={onMinusButtonClickHandler}>-</button>
<div style={{ display: "flex", margin: "10px" }}>
<Box1 initCount={initCount} />
<Box2 />
<Box3 />
</div>
</>
);
}
- Box1 ์ปดํฌ๋ํธ๋ ๋ถ๋ชจ์ปดํฌ๋ํธ์์ ๋ฐ์ count๋ฅผ ์ด๊ธฐํ์ํค๋ ํจ์ initCount ํจ์๋ฅผ props๋ก ๋ฐ์ ์ฐ๊ณ ์๋ค.
- ์ด๋ด ๊ฒฝ์ฐ์ App.jsx ์์ + - ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ์ count๊ฐ ๊ฐฑ์ ๋๋ฉด์ ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋๋ค. ์ด ๋ ํจ์๋ฅผ props๋ก ๋ฐ์Box1๋ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๋ค. ์์์ ์ธ๊ธํ๋ฏ์ด Box1์ React.memo๋ก ๊ฐ์ธ์ ธ์๋ ์ํ์ธ๋ฐ๋ ๋ถ๊ตฌํ๊ณ ๋ง์ด๋ค.
- initCount ํจ์๋ count๋ฅผ ์ด๊ธฐํํด์ฃผ๋ ํจ์๋ผ๊ณ ๋งํ๋ค. ํจ์์ฝ๋๊ฐ ๋ฐ๋์๋๊ฐ? ์๋๋ค. ํจ์๋ ํจ์์ด์ง state ๊ฐ ์๋๋ค. ๋ถ๋ช
Box1์ ํจ์๋ฅผ props๋ก ๋ฐ์๋๋ฐ ์ props๋ก ๋ด๋ ค์จ ๊ฐ์ด ๋ฐ๋์๋ค๊ณ ํ๋จํ์๊น? ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ์์ ํจ์๋ ๊ฐ์ฒด์ ํ ์ข ๋ฅโญ๋ผ๊ณ ๋ณธ๋ค.
- ๋ณ์ ์์ญ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ณ๋์ ๊ณต๊ฐ์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ์ฃผ์๊ฐ์ ์ ์ฅํ๋ค.
- ๋ค์ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๋ฉด ์ด์ ์ ์์๋ ํจ์๋ค์ ๊ทธ๋๋ก ์๊ณ ์๋ก์ด ๊ฐ initCount๋ฅผ ์๋ก์ด ๊ณต๊ฐ์ ์ ์ฅ์ ํ๊ฒ ๋๋ค.
- initCount๋ ๊ฒฐ๊ตญ ์๋ก์ด ์ฃผ์๋ฅผ ๊ฐ๊ฒ ๋๋ ๊ฒ์ด๋ค. ๋ฆฌ์กํธ๋ ๋ณ์ ์์ญ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ก์ด ์ฃผ์๊ฐ์ ๊ฐ์ง๋ฉด ๋ ๋๋ง์ ํ๋ค.
- ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Box1 ์ ์ฅ์์๋ props๊ฐ ๋ฐ๋์๋ค๊ณ ํ๋จํ์ฌ ๋ฆฌ๋ ๋๋ง์ ํ๋ ๊ฒ์ด๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ
์ด๋ด ๋๋ initCount๋ฅผ ๋ค์๊ณผ ๊ฐ์ด useCallback์ผ๋ก ๊ฐ์ธ์ผ ํ๋ค.
React.memo ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ค๋ฉด, useCallback์ ์ธ์๋ก ๋ค์ด์ค๋ ํจ์ ์์ฒด๋ฅผ ๊ธฐ์ต(๋ฉ๋ชจ์ด์ ์ด์ )ํ๋ค.
useCallback ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์์กด์ฑ ๋ฐฐ์ด์ ๋ ๋ฒ ์งธ ์ธ์๋ก ๋ฐ๋๋ค.
// ๋ณ๊ฒฝ ์
const initCount = () => {
setCount(0);
};
// ๋ณ๊ฒฝ ํ
const initCount = useCallback(() => {
setCount(0);
}, []);
์ด๋ ๊ฒ ํ๋ฉด ์ ์์ ์ผ๋ก ์์ ์ปดํฌ๋ํธ์ ๋ถํ์ํ ๋ ๋๋ง์ ๋ง์ ์ ์๋ค.
๋ฌธ์ 2
์ซ์๋ฅผ ๋ฐ๊ฟจ๋ค๊ฐ ์ด๊ธฐํ๋ฅผ ์ํค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ์์ ์ฐ๊ฒ ํ๊ณ ์ ํ๋ค.
const initCount = useCallback(() => {
console.log(`${count}์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.`);
setCount(0);
}, []);

์ฝ๋๋ฅผ ๋ณ๊ฒฝ ํ์ ์ซ์๋ฅผ 3๊น์ง ๋๋ฆฐ ํ์ ์ด๊ธฐํ ๋ฒํผ์ ๋๋ฆ์ผ๋ก์จ initCount useCallback๋ฌธ์ ์ฝ์์ ์ฐ์ด๋ณด์๋ค.
count๋ ๋ช์ผ๋ก ๋์ฌ๊น? ์๋ ์๋๋ '3์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค'๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ์ด๋ค.
ํ์ง๋ง ๊ฒฐ๊ณผ๋ '0์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.' ๋ผ๊ณ ์ฝ์์ ์ฐ์๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
โ โญ useCallback์ด ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ๋ ์์ ์ ์ฒ์์ App.jsx ์ปดํฌ๋ํธ๊ฐ ๊ทธ๋ ค์ง๋ ์์ ์ด๋ค.โญ ์ด ์์ ์ useCallback์ด initCount๋ฅผ ์ด๋ค ๋ชจ์์ผ๋ก ๋ฉ๋ชจ์ด์ ์ด์ ํ๋์ง ๋ณด์.
() => {
console.log(`${count}์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.`);
setCount(0);
}
์ด์ ๊ฐ์ ๋ชจ์ ๊ทธ๋๋ก ์ ์ฅ์ ํ๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ๋ ์์ ์ ์ฒ์์ App.jsx๊ฐ ๊ทธ๋ ค์ง๋ ์์ ์ด๋ผ๊ณ ์ธ๊ธํ์๋ค. ์ด ๋์ count๊ฐ์ ?
const [count, setCount] = useState(0);
0์ด๋ค. ๊ทธ๋์ count ๊ฐ 0์ธ ์ํ๋ก ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ ์ฅ๋์ด ์๋ ๊ฒ์ด๋ค.
=> ์ด๊ธฐ๊ฐ์ 3์ผ๋ก ์ค์ ํด๋๋ฉด '3์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค' ๋ผ๊ณ ์ฝ์์ ์ฐ๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ
์ฝ์์ ์ ๋๋ก ๋ฟ๋ ค์ฃผ๊ธฐ ์ํด์๋ count ๊ฐ ๋ฐ๋ ๋ ๋งํผ์ ๋ค์ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋๋ก ํด์ผ ํ๋ค.
๊ทธ๋ด ๋! ์์กด์ฑ ๋ฐฐ์ด๊ฐ์ ์ฐ๋ ๊ฒ์ด๋ค. ๊ทธ state ๊ฐ์ ์ถ์ ํ๊ฒ ๋๋ค.
const initCount = useCallback(() => {
console.log(`${count}์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.`);
setCount(0);
}, [count]);

6๋ฒ ์ฌ๋ฆฐ ํ ์ด๊ธฐํ๋ฅผ ๋๋ฅด๋ฉด ์ ์์ ์ผ๋ก '6์์ 0์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค' ๋ฅผ ์ฝ์์ ์ฐ๋๋ค.('Box1 ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋์์ต๋๋ค' ์ฝ์์ ์์กด์ฑ ๋ฐฐ์ด๊ฐ์ผ๋ก count๋ฅผ ๋ฃ์๊ธฐ ๋๋ฌธ์ ๋ณ๊ฒฝ์ด ์์ ๋๋ง๋ค ์ฐํ๊ฒ ๋๋ ๊ฒ์ด๋ค. ์ฃผ์ ์ฒ๋ฆฌํ์.)
2-3. useMemo
- ๊ฐ์ ๋ํ ๋ฉ๋ชจ์ด์ ์ด์ ๊ธฐ๋ฅ์ ํด์ค๋ค.
- ์ฌ๊ธฐ์ ๊ฐ์ ํจ์๊ฐ return ํ๋ ๊ฐ ๋๋ ๊ทธ๋ฅ ๊ฐ ๊ทธ ์์ฒด์ด๋ค.
- ๋ฌด๊ฑฐ์ด ์์ ์ํ ์ ๋์์ด ๋๋ค.
ํํ
const heavyWork = () => {
for (let i = 0; i < 1000000000000000; i++) {
return 100;
}
};
const value = useMemo(() => heavyWork(), []);
์ฌ์ฉ ์์ 1 : ๋ฌด๊ฑฐ์ด ์์ ์ ํ ๋ ์ฌ์ฉ
๋ฌด๊ฑฐ์ด ์์ useMemo ์ฌ์ฉ ์ ํ ์ฐจ์ด๋ฅผ ๋ชธ์ ๋๋ผ๋๊ฒ ๋ ๋์์ด ๋ ๋ฏ.
[ App.jsx ]
import HeavyComponent from "components/HeavyComponent";
import React from "react";
import styled from "styled-components";
const Stnav = styled.nav`
background-color: yellow;
margin-bottom: 30px;
`;
const Stfooter = styled.footer`
background-color: green;
margin-bottom: 30px;
`;
// heavy work -> ์์ฒญ ๋ฌด๊ฑฐ์ด ์์
...!!
function App() {
return (
<>
<Stnav>๋ค๋น๊ฒ์ด์
๋ฐ</Stnav>
<HeavyComponent />
<Stfooter>ํธํฐ ์์ญ์ด์์.</Stfooter>
</>
);
}
export default App;
[ HeavyComponent.jsx ]
import React, { useMemo, useState } from "react";
function HeavyComponent() {
const [count, setCount] = useState(0);
const countHandler = () => {
setCount(count + 1);
};
const heavyWork = () => {
for (let i = 0; i < 1000000000000000; i++) {
return 100;
}
};
// const value = heavyWork();
const value = useMemo(() => heavyWork(), []);
console.log(`value๋ ${value}์
๋๋ค.`);
return (
<>
<p>๋๋ ์์ฒญ ๋ฌด๊ฑฐ์ด ์ปดํฌ๋ํธ์ผ!</p>
<button onClick={countHandler}>
๋๋ฅด๋ฉด ์๋ count๊ฐ ์ฌ๋ผ๊ฐ์!
</button>
<br />
{count}
</>
);
}
export default HeavyComponent;
์ฌ์ฉ ์์ 2 : ๋ณ๊ฒฝ๋์ง ์์์์ ๋ช ์
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์๋ ์๋ค. ๋ค์ ์์์ฝ๋์์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ๋ฅผ ๋ณด์.
[ ์์ ์ฝ๋ ]
import React, { useEffect, useState } from "react";
function ObjectComponent() {
const [isAlive, setIsAlive] = useState(true);
const [uselessCount, setUselessCount] = useState(0);
const me = {
name: "Ted Chang",
age: 21,
isAlive: isAlive ? "์์กด" : "์ฌ๋ง",
};
useEffect(() => {
console.log("์์กด์ฌ๋ถ๊ฐ ๋ฐ๋ ๋๋ง ํธ์ถํด์ฃผ์ธ์!");
}, [me]);
return (
<>
<div>
๋ด ์ด๋ฆ์ {me.name}์ด๊ตฌ, ๋์ด๋ {me.age}์ผ!
</div>
<br />
<div>
<button
onClick={() => {
setIsAlive(!isAlive);
}}
>
๋๋ฅด๋ฉด ์ด์๋ค๊ฐ ์ฃฝ์๋ค๊ฐ ํด์
</button>
<br />
์์กด์ฌ๋ถ : {me.isAlive}
</div>
<hr />
ํ์์๋ ์ซ์ ์์ญ์ด์์!
<br />
{uselessCount}
<br />
<button
onClick={() => {
setUselessCount(uselessCount + 1);
}}
>
๋๋ฅด๋ฉด ์ซ์๊ฐ ์ฌ๋ผ๊ฐ์
</button>
</>
);
}
export default ObjectComponent;
- ์ฝ๋๋ isAlive ๊ฐ์ ๋ฐ๋ผ์ me ๊ฐ์ฒด์ ๋ด๋ถ ๊ฐ์ด ๋ฌ๋ผ์ง๊ณ ๊ทธ์ ๋ฐ๋ผ ๋ ๋๋ง์ด ๋ฐ์ํ๋ค.
- ๊ทผ๋ฐ ์ด๊ฒ์ useEffect์ ์์กด์ฑ ๋ฐฐ์ด๊ฐ์ me๋ฅผ ์ค์ผ๋ก์จ me๊ฐ ๋ฐ๋ ๋๋ง console์ ์ฐ๋๋ก ์๋ํ์๋ค.
- ๊ทธ๋ฆฌ๊ณ me ๊ฐ์ฒด์ ์๋ฌด ๊ด๋ จ์ด ์๋ uselessCount state๊ฐ ์๋ค. ์๋ฌด ๊ด๋ จ ์๋ uselessCount ๊ฐ์ด ๋ฐ๋์์ ๋๋ useEffect ๋ฌธ์ ์ฝ์์ด ์ฐํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ ๊ฒ์ด๋ค.
ํ์ง๋ง ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.

- ์๋ฌด ๊ด๋ จ ์๋ ์ซ์๋ฅผ ์ฌ๋ ธ๋๋ useEffect๋ฌธ์ ์ฝ์์ด ์ฐํ๋ค. ๋ถ๋ช ์์กด์ฑ ๋ฐฐ์ด๊ฐ์ me๋ฅผ ๋ฃ์์์๋ ๋ถ๊ตฌํ๊ณ ๋ง์ด๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- โญํจ์ํ ์ปดํฌ๋ํธ๊ฐ ํธ์ถ๋๋ฉด ์ปดํฌ๋ํธ๊ฐ ์๋กญ๊ฒ ๋ง๋ค์ด์ง๋ฉด์ ๋ชจ๋ ๋ด๋ถ ์์๋ค๋ ์๋กญ๊ฒ(์ฐธ์กฐํ ๋ฐ์ดํฐ๋ ์์ ์๋ก์ด ์ฃผ์๋ฅผ ๊ฐ์ง) ๋ง๋ค์ด์ง๋ค.โญ
- state๊ฐ ๋ฐ๋๋ฉด ๋ ๋๋ง์ด ๋ฐ์ํ๋ ๊ฒ์ ์๊ณ ์์ ๊ฒ์ด๋ค.
- ์ด ๋ ์ปดํฌ๋ํธ ํจ์๊ฐ ํธ์ถ์ด ๋๋ค. ์ด ๋ me ๊ฐ์ฒด๋ ๋ค์ ํ ๋น์ด ๋๋ ๊ฒ์ด๋ค.(์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ํ ๋น๋ฐ๋๋ค.)๊ทธ๋ฌ๋ฉด ๋ฆฌ์กํธ ์ ์ฅ์์๋ me ๊ฐ์ฒด๊ฐ ๋ฐ๋์๋ค๊ณ ์ธ์ํ๊ณ useEffect ๋ด๋ถ ๋ก์ง์ด ํธ์ถ๋๊ฒ ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
const me = useMemo(() => {
return {
name: "Ted Chang",
age: 21,
isAlive: isAlive ? "์์กด" : "์ฌ๋ง",
};
}, [isAlive]);
useEffect(() => {
console.log("์์กด์ฌ๋ถ๊ฐ ๋ฐ๋ ๋๋ง ํธ์ถํด์ฃผ์ธ์!");
}, [me]);
- useMemo ๋ก ๊ฐ์ฒด๋ฅผ ๊ฐ์ธ๊ณ ์์กด์ฑ ๋ฐฐ์ด๊ฐ์ me ๊ฐ์ฒด์ ๋ณ๋์ ์ฃผ๋ isAlive state๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
- me ๊ฐ์ฒด๋ memoization์ด ๋์ด ์์ด์ isAlive ๊ฐ์ด ๋ฐ๋ ๋์๋ง ๊ฐฑ์ (๋ค์ ๋ฉ๋ชจ์ด์ ์ด์ )์ด ์ด๋ค์ง๋ ๊ฐ์ฒด๊ฐ ๋ ๊ฒ์ด๋ค.
- ์ฌ์ ํ ์๊ด์๋ uselessCount state๋ฅผ ์ฌ๋ ค๋ ํจ์ ์ปดํฌ๋ํธ๊ฐ ๋ค์ ์๋กญ๊ฒ ๋ ๋๋ง๋์ง๋ง, me๊ฐ ๊ฐฑ์ ์ด ๋์ง ์์(์ต์ด์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด๋จ๋ ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ๋ค์ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์) useEffect ๋ฌธ์ด ์คํ์ด ์ ๋๋ค. ์ฆ, ์ฝ์์ ์ฐ์ง ์๋๋ค.
*์ฐธ๊ณ ๋ก vsCode๊ฐ ์ด๋ฐ ๋ฌธ์ ๋ ์๋์ผ๋ก ์บ์นํด์ค๋ค

vscode ์์ฒด์์๋ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ๊ณ useMemo ์ฌ์ฉ์ ์ถ์ฒํด์ค๋ค ๐
๐จ์ฃผ์์ฌํญ
์บ์ฑ ๊ธฐ๋ฅ์ ๊ฐ์ง ํ ์ ๋จ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ ํ๋ณด๋ฅผ ๋๋ฌด ๋ง์ด ํ๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์คํ๋ ค ์ฑ๋ฅ์ด ์ ํ๋ ์ ์๋ค.
ํ๋ก๊ทธ๋จ์ด ํ๋ก์ธ์ค๋ก์ ๋์๊ฐ๋ ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ๋ฐ์์ผ ํ๋๋ฐ ์ด๋ฌํ ์ค์ํ ๊ณต๊ฐ์ด ๋ถ์กฑํด์ง๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ ํ์ํ ๋๋ง ์ฐ๋๋ก ํ์.