๋ฆฌ์กํธ๋ก ํ๋ก์ ํธ๋ฅผ ์งํํ๋ค๋ณด๋ฉด ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ๋ณต๋๋ ๋ฑ, ๋ค์๊ณผ ๊ฐ์ ์ฑ๋ฅ ์ด์๋ฅผ ๋ง์ฃผํ๊ฒ ๋๋ค.
์ด๋ฌํ ๋ถํ์ํ ๋ฐ๋ณต๋ค์ ์ค์ด๊ธฐ ์ํด์ โ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ตโํด๋๊ณ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ธ ๋ฉ๋ชจ์ด์ ์ด์ (Memoization)์ ํตํด ์ฑ๋ฅ ์ต์ ํ๋ฅผ ํ ์ ์๋ค.
๋ฉ๋ชจ์ด์ ์ด์ (Memoization)์ด๋ ๋์ผํ ๊ณ์ฐ์ ๋ฐ๋ณตํด์ผ ํ ๋, ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด ๋์๋ค๊ฐ ๊บผ๋ด ์์ผ๋ก์จ ์ค๋ณต ๊ณ์ฐ์ ์ ๊ฑฐํ์ฌ ํ๋ก๊ทธ๋จ ์คํ ์๋๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ ๊ธฐ๋ฒ์ด๋ค. ์บ์ฑ(caching)์ด๋ผ๋ ๋จ์ด์ ๋น์ทํ๋ค.
๋ฆฌ์กํธ์์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ์ฉํ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก React.memo, useMemo, useCallback ๋ฑ์ด ์๋ค.
uesMemo๋ memoized๋ โ๊ฐโ์ ๋ฐํํ๋ ํ ํจ์๋ก, fn ํจ์์ ๊ฒฐ๊ณผ๋ฅผ dependencies๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์บ์ฑํ๋ค.
const cachedValue = useMemo(fn, dependencies)
useCallback์ memoized๋ โํจ์โ๋ฅผ ๋ฐํํ๋ ํ ํจ์๋ก, ์ ๋ฌ๋ fn ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ์ฌ ์บ์ฑํ๋ค. dependencies์ ํฌํจ๋ ๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์๋๋ค๋ฉด ์บ์ฑํด๋ fn ํจ์์ ์ฐธ์กฐ ๊ฐ์ ๊ทธ๋๋ก ๋ฐํํ๋ค.
const cachedFn = useCallback(fn, dependencies)
React.memo๋ ์ปดํฌ๋ํธ ์์ฒด๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ค.
import { memo } from 'react';
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
๊ณ ์ฐจ ์ปดํฌ๋ํธ๋, ์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฐ์์ ์๋ก์ด ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ๋งํ๋ค.
๊ณ ์ฐจ ์ปดํฌ๋ํธ์ธ React.memo๋ ์ธ์๋ก ๋ฐ์ ์ปดํฌ๋ํธ์ props์ ๋ณํ๋ฅผ ์ฒดํฌํ์ฌ ์ปดํฌ๋ํธ ์ต์ ํ๋ฅผ ์งํํ๋ค.
React.memo๋ props์ ๋ณํ๋ฅผ ์ฒดํฌํ ๋ ์์ ๋น๊ต๋ฅผ ํตํด ๋ณํ๋ฅผ ํ์ธํ๋ค.
์ฆ ์์๊ฐ์ ๊ฒฝ์ฐ ์ด์ ๊ณผ ๋์ผํ ๊ฐ์ธ์ง ๋น๊ตํ๊ณ , ๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ์ ์ฐธ์กฐ ํ์ ๊ฐ์ ๊ฒฝ์ฐ ์ด์ ๊ณผ ๋์ผํ ์ฃผ์๊ฐ์ธ์ง๋ฅผ ๋น๊ตํ๋ค.
React.memo์ ์ธ์๋ก ๋ฐ์ ์ปดํฌ๋ํธ์ props์ ๋ณํ๊ฐ ์๋ค๋ฉด ๋ ๋๋ง์ ํ๊ณ , props์ ๋ณํ๊ฐ ์๋ค๋ฉด ๋ ๋๋ง ํ์ง ์๊ณ ๊ธฐ์กด์ ๋ ๋๋ง ๋ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฌ์ฉํ๋ค.
const Profile = ({info}) => {
return (
<p>name: {info.name}</p>
<p>age: {info.age}</p>
)
}
export default React.memo(Profile);
๋ถํ์ํ ๋ฆฌ๋ ๋๋ง, ๋ณต์กํ ๊ณ์ฐ์ ๋ฐ๋ณต ๋ฑ์ ์ค์ด๊ธฐ ์ํ ์ฉ๋๋ก, ๋ฉ๋ชจ์ด์ ์ด์ ์ ํตํด ์ฑ๋ฅ ์ต์ ํ๋ฅผ ํ๋ ๊ฒ์ด ๊ทธ ๋ชฉ์ ์ด๋ค.
React.memo๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ก ํจ์ ์ปดํฌ๋ํธ ๋ฟ๋ง ์๋๋ผ ํด๋์ค ์ปดํฌ๋ํธ์๋ ์ฌ์ฉ ๊ฐ๋ฅํ์ง๋ง useMemo์ useCallback์ ํ ์ผ๋ก ํจ์ ์ปดํฌ๋ํธ์์๋ง ์ฌ์ฉํ ์ ์๋ค.
useMemo๋ ์ ๋ฌ๋ ํจ์๊ฐ ์คํ๋๊ณ ๋ฐํ๋ ๊ฐ์ ์บ์ฑํ์ง๋ง useCallback์ ์ ๋ฌ๋ ํจ์ ๊ทธ ์์ฒด๋ฅผ ์บ์ฑํ๋ค.
React.memo๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ํฉํ ์ํฉ์
React.memo๋ ์ค์ง props ๋ณํ์๋ง ์์กดํ๋ ์ต์ ํ ๋ฐฉ๋ฒ์ด๋ค.
๋ง์ฝ์ ์ปดํฌ๋ํธ๊ฐ useState, useReducer, useContext์ ๊ฐ์ ์ํ ๊ด๋ จ ํ ์ ์ฌ์ฉํ๋ค๋ฉด, props์ ๋ณํ๊ฐ ์๋๋ผ๋ ์ฌ์ ํ state๋ context๊ฐ ๋ณํ ๋๋ง๋ค ๋ค์ ๋ ๋๋ง ๋ ๊ฒ์ด๋ค.
React.memo๋ฅผ ์ ์ฌ์ฉํ๋ค๋ฉด ๋ ๋๋ง ํ์ ๊ฐ์๋ก ์ธํด ์ด๋์ ๋ณผ ์ ์์ง๋ง, ๋ฌด๋ถ๋ณํ ์ฌ์ฉ์ ์คํ๋ ค ๋ ์ด ๋ ์๋ ์๋ค.
์๋ํ๋ฉด ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์งํ ๋ ๋ ๋๋ง ๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋๊ฐ์ ์ ์ฅํด๋์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์๋นํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์ฝ props๊ฐ ๊ณ์ ๋ณํ๋ ์ปดํฌ๋ํธ๋ฅผ React.memo๋ก ๊ฐ์ผ๋ค๋ฉด ๋ถํ์ํ ๋น๊ต๊ณผ์ ๋ง ๊ฑฐ์น ๋ฟ ๋ ๋๋ง์ ๋ฐ๋ณต์ ์ผ๋ก ๋ฐ์ํ ๊ฒ์ด๋ค.
props์ ๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ ์ฐธ์กฐ ํ์ ์ ๊ฐ์ ์ ๋ฌํ ๊ฒฝ์ฐ ์์ ์ปดํฌ๋ํธ๊ฐ ํธ์ถ๋ ๋๋ง๋ค ๋งค๋ฒ ์๋ก ์์ฑ๋๋ ์ฐธ์กฐ๊ฐ์ ๋งค๋ฒ ์๋ก์ด ์ฃผ์๊ฐ์ ๊ฐ์ง๊ฒ ๋๋ค. ์์ ๋น๊ต๋ฅผ ํตํด React.memo์ ์ ์ฅ์์๋ props์ ๋ณํ๊ฐ ์๋ค๊ณ ํ๋จํ๋ค.
๋ฐ๋ผ์ ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๊ฐ์ ์ฌ์ฉํ์ง ์๊ณ ๋ ๋๋ง์ด ๋ค์ ๋ฐ์ํ๋ค.
import Profile from './Profile';
const App = () => {
const info = {
name: 'kim',
age: 20,
};
return (
<Profile info={info} /> // App์ด ๋ ๋๋ง ๋ ๋๋ง๋ค props๊ฐ ๋ฌ๋ผ์ง
)
};
React.memo๋ก ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์์ง๋ง props์ ์ฐธ์กฐ ํ์ ์ ๊ฐ์ด ์ ๋ฌ๋ ๊ฒฝ์ฐ ํด๋น ์ฐธ์กฐ๊ฐ์ useMemo๋ก ๊ฐ์ธ์ ๋์ผํ ์ฐธ์กฐ๋ฅผ ๋ณด์ฅํ๋ค๋ฉด ์๋ํ ๋๋ก ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ง์ ์ ์๋ค.
import { useMemo } from 'react';
import Profile from './Profile';
const App = () => {
const info = useMemo(() => {
return {
name: 'kim',
age: 20,
};
}, []);
return (
<Profile info={info} />
)
};
React.memo๋ก ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์์ง๋ง props์ ํจ์๊ฐ ์ ๋ฌ๋ ๊ฒฝ์ฐ ํด๋น ํจ์๋ฅผ useCallback์ผ๋ก ๊ฐ์ธ์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋งค๋ฒ ํธ์ถ๋ ๋๋ง๋ค ํจ์์ ๋์ผํ ์ฐธ์กฐ๋ฅผ ๋ณด์ฅํ๋ค๋ฉด ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ง์ ์ ์๋ค.
import { useCallback } from 'react';
import Profile from './Profile';
const App = () => {
const sayHi = useCallback(() => {
console.log('hi');
}, []);
return (
<Profile sayHi={sayHi} />
)
};