| title | use-memo |
|---|
useMemo Hook์ด ๋ฐํ๊ฐ๊ณผ ํจ๊ป ์ฌ์ฉ๋๋์ง ๊ฒ์ฆํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ useMemo ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
useMemo๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฐ์ ๊ณ์ฐํ๊ณ ์บ์ฑํ๊ธฐ ์ํ ๊ฒ์ด์ง ๋ถ์ ํจ๊ณผSide Effect๋ฅผ ์ํ ๊ฒ์ด ์๋๋๋ค. ๋ฐํ๊ฐ์ด ์์ผ๋ฉด useMemo๋ undefined๋ฅผ ๋ฐํํ์ฌ ๋ชฉ์ ์ ๋ฌ์ฑํ์ง ๋ชปํ๋ฉฐ, ์๋ชป๋ Hook์ ์ฌ์ฉํ๊ณ ์์์ ๋ํ๋ผ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
์ด ๊ท์น์ ๋ํ ์๋ชป๋ ์ฝ๋ ์์์ ๋๋ค.
// โ ๋ฐํ๊ฐ ์์
function Component({ data }) {
const processed = useMemo(() => {
data.forEach(item => console.log(item));
// return ๋๋ฝ!
}, [data]);
return <div>{processed}</div>; // ํญ์ undefined
}์ด ๊ท์น์ ๋ํ ์ฌ๋ฐ๋ฅธ ์ฝ๋ ์์์ ๋๋ค.
// โ
๊ณ์ฐ๋ ๊ฐ ๋ฐํ
function Component({ data }) {
const processed = useMemo(() => {
return data.map(item => item * 2);
}, [data]);
return <div>{processed}</div>;
}๋ถ์ ํจ๊ณผSide Effect์ useMemo๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ ์ ์์ต๋๋ค.
{/* TODO(@poteto) fix compiler validation to check for unassigned useMemos */}
// โ ์๋ชป๋ ์์: useMemo์์ ๋ถ์ ํจ๊ณผ
function Component({user}) {
// ๋ฐํ๊ฐ ์์, ๋ถ์ ํจ๊ณผ๋ง
useMemo(() => {
analytics.track('UserViewed', {userId: user.id});
}, [user.id]);
// ๋ณ์์ ํ ๋น๋์ง ์์
useMemo(() => {
return analytics.track('UserViewed', {userId: user.id});
}, [user.id]);
}๋ถ์ ํจ๊ณผ๊ฐ ์ฌ์ฉ์ ์ํธ์์ฉ์ ๋ํ ์๋ต์ผ๋ก ๋ฐ์ํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ถ์ ํจ๊ณผ๋ฅผ ์ด๋ฒคํธ์ ํจ๊ป ๋ฐฐ์นํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.
// โ
์ข์ ์์: ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ๋ถ์ ํจ๊ณผ
function Component({user}) {
const handleClick = () => {
analytics.track('ButtonClicked', {userId: user.id});
// ๊ธฐํ ํด๋ฆญ ๋ก์ง...
};
return <button onClick={handleClick}>Click me</button>;
}๋ถ์ ํจ๊ณผ๊ฐ React state๋ฅผ ์ธ๋ถ state์ ๋๊ธฐํํ๋ ๊ฒฝ์ฐ(๋๋ ๊ทธ ๋ฐ๋) useEffect๋ฅผ ์ฌ์ฉํ์ธ์.
// โ
์ข์ ์์: useEffect์์ ๋๊ธฐํ
function Component({theme}) {
useEffect(() => {
localStorage.setItem('preferredTheme', theme);
document.body.className = theme;
}, [theme]);
return <div>ํ์ฌ ํ
๋ง: {theme}</div>;
}