React์ Hook ์ค์ useCallback๊ณผ useMemo๋ฅผ ํ์ฉํ์ฌ ์ต์ ํ ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์๋ค.
์ฃผ๋ชฉํด์ผ ๋ ์ ์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋์์๋ ์์ ์ปดํฌ๋ํธ๊น์ง ๋ค์ ๋ ๋๋ง์ด ๋๋ค. ํ์ง๋ง ์์์ปดํฌ๋ํธ๋ ๋ณํ์ ์๋ฌด๋ฐ ์ํฅ์ด ์๋ค๋ฉด ๋ถํ์ํ ๋ ๋๋ง์ด ๋ฐ์ํ์ฌ ์ฑ๋ฅ ์์ค์ด ๋ฐ์ํ๊ฒ ๋๋ค. ์ฆ ์ปดํฌ๋ํธ๊ฐ ๋ณต์กํ๊ณ ๋ง์์๋ก ์์ค์ ์ฌํด์ง๊ฒ ๋๋ค.
import React from "react";
import ReactDOM from "react-dom";
const CountButton = function CountButton({ count, onClick }) {
return <button onClick={onClick}>{count}</button>;
};
function DualCounter() {
const [count1, setCount1] = React.useState(0);
const increment1 = () => { setCount1(c => c + 1) };
const [count2, setCount2] = React.useState(0);
const increment2 = () => { setCount2(c => c + 1) };
return (
<>
<CountButton count={count1} onClick={increment1} />
<CountButton count={count2} onClick={increment2} />
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<DualCounter />, rootElement);
์์ฃผ ๊ฐ๋จํ ์์์ด๋ค ์ ์ฝ๋๋ increment1 ์ ํธ์ถ์ํค๋ฉด count1์ด 1 ๋ํด์ง๋ฉฐ state ๊ฐ ๋ณ๊ฒฝ๋์ด ๋ฆฌ๋ ๋๋ง ๋๋ค. ๊ทธ๋ ๊ฒ๋๋ฉด ์ ๋ณํ์ ์๋ฌด๋ฐ ๋ณ๊ฒฝ์ด ์์ด๋ count2๋ ๋ถ๋ชจ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง์ด ๋์ด ๋ฆฌ ๋ ๋๋ง์ด ์ด๋ฃจ์์ง๋ค
shouldComponentUpdate ๊ฐ ์๋ฏ์ด React.memo ๊ฐ ์๋ค ์ ์์ ๋ฅผ memo์ useCallback ์ฌ์ฉํ๋ฉด ๋ถํ์ํ ๋ฆฌ ๋ ๋๋ง์ ๋ง์ ์ ์๋ค.
const CountButton = React.memo(function CountButton({ count, onClick }) {
return <button>{count}</button>;
});
function DualCounter() {
const [count1, setCount1] = React.useState(0);
const increment1 = () => { setCount1(c => c + 1) };
const [count2, setCount2] = React.useState(0);
const increment2 = () => { setCount2(c => c + 1) };
return (
<>
<CountButton count={count1} onClick={increment1} />
<CountButton count={count2} onClick={increment2} />
</>
);
}
์ ์์ ์์๋ memo๋ง ์ฌ์ฉํ์๋ค. React.memo()๋ props ํน์ props์ ๊ฐ์ฒด๋ฅผ ๋น๊ตํ ๋ ์์(shallow) ๋น๊ต๋ฅผ ํ๋ค. ๊ทธ๋ ๊ฒ ๋๋ค๋ฉด count๊ฐ์ ๋ถ๋ณ๊ฐ์ด๋ ์๊ด์ด ์์ผ๋ onClick์ ๋ฆฌ ๋ ๋๋ง ๋ ๋๋ง๋ค ์๋ก ์์ฑ๋์ด ๋ฆฌ ๋ ๋๋ง ๋๋ค.
function DualCounter() {
const [count1, setCount1] = React.useState(0);
const increment1 = React.useCallback(() => setCount1(c => c + 1), []);;
const [count2, setCount2] = React.useState(0);
const increment2 = React.useCallback(() => setCount2(c => c + 1), []);;
return (
<>
<CountButton count={count1} onClick={increment1} />
<CountButton count={count2} onClick={increment2} />
</>
);
}
์ ์์ค๋ฅผ ๋ณด๋ฉด ์ฆ๊ฐํ๋ ํจ์๋ฅผ useCallback์ผ๋ก ๊ฐ์ธ๊ณ ๋๋ฒ์งธ ์ธ์์ ์์กด์ฑ ๊ฐ๋ค์ ๋ฃ์ด์ฃผ๊ณ ํด๋น ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ๊ฐ์ง๋ฅผ ํ์ฌ ์๋ก์ด ํจ์๋ฅผ ๋ง๋ ๋ค. ์ด๋ฒ์ ๋น ๋ฐฐ์ด์ ๋๊ฒจ์ค์ ์๋ก์ด ํจ์๋ฅผ ๋ง๋ค์ง ์๋๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด onClick๊ฐ์ด ๋ณํ์ง ์์ผ๋ฏ๋ก ๋ฆฌ ๋ ๋๋ง ๋์ง ์๋๋ค. ํน์ React.memo์ ๋๋ฒ์งธ ์ธ์์ ์กฐ๊ฑด์ ๊ฑฐ๋ ๋ฐฉ์์ด ์๋ค.
useCallback์ ํจ์๋ง ๋ฐํํ๋ค ์๊ฐํ๊ณ useMemo๋ ๊ฐ(ํจ์ํฌํจ) ๋ฐํ ํ ์ ์๋ค. ์ฃผ๋ก ๋ณต์กํ๊ณ ์ค๋๊ฑธ๋ฆฌ๋ ์์ ์ ์ฌ์ฉํด์ผ๋๋ค.