useMemo
์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฉ๋ชจ์ ์ด์
๊ธฐ๋ฒ์ ์ด์ฉํ Hook์ผ๋ก, ํจ์์ ์ฌ์ฌ์ฉ์ ์ํด ์ฌ์ฉํ๋ Hook์ด๋ค.
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
์์ ์์๋ useCallback
์ฌ์ฉ์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ก, ๋ ๋ฒ์งธ ์ธ์์ธ ์์กด์ฑ์ด ๋ณ๊ฒฝ๋์์ ๋๋ง ๋ค์ ๋ฉ๋ชจ์ ์ด์
๋ ๋ฒ์ ์ด ๋ณ๊ฒฝ๋๋ค.
import React, { useCallback } from "react";
function Calculator({x, y}){
const add = useCallback(() => x + y, [x, y]);
return
<>
<div>
{add()}
</div>
</>;
}
์์ ์์๋ props๋ก ๋ฐ์ x, y๊ฐ์ add
ํจ์์ ์ธ์๋ก ๋๊ฒจ์ ๊ฐ์ ๋ํ์ฌ<div>
ํ๊ทธ์ ๋ํ ๊ฐ์ ์ถ๋ ฅํ๊ณ ์๋ ์ฝ๋์ด๋ค.
๋ง์ฝ x, y๊ฐ์ด ์ง์์ ์ผ๋ก ๋ฐ๋์ง ์๋๋ค๊ณ ๊ฐ์ ํ์ ๋, useCallback
Hook์ ์ฌ์ฉํ๋ค๋ฉด ๊ธฐ์กด ํจ์๋ฅผ ๊ณ์ํด์ ๋ฐํํ๋ฉฐ, ๋ค์ ๋ ๋๋ง ๋ ๊ธฐ์กด ํจ์๋ฅผ ๋ค์ ์ฌ์ฉํ๋ค.
React๋ ๊ธฐ๋ณธ์ ์ผ๋ก JavaScript์ ๋ฌธ๋ฒ์ ๋ฐ๋ผ๊ฐ๋ฉฐ, JavaScript์์ ํจ์๋ ๊ฐ์ฒด์ด๋ค.
๊ฐ์ฒด๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ ๋, ๊ฐ์ด ์๋ ์ฃผ์๋ฅผ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๋ฐํ ๊ฐ์ด ๊ฐ๋๋ผ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ค๊ณ ๋ณผ ์ ์๋ค.
๋ฐ๋ผ์, ์๋ก ๋ง๋ค์ด ํธ์ถ๋ ํจ์๋ ๊ธฐ์กด์ ํจ์์ ๊ฐ์ ํจ์๊ฐ ์๋๋ค.
๊ทธ๋ฌ๋ useCallback
์ ์ด์ฉํด ํจ์ ์์ฒด๋ฅผ ์ ์ฅํด์ ์ฌ์ฌ์ฉ ์, ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ์ ์ ์ฅํ๋ค๊ฐ ์ฌ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ ๋ชฉ์ ์ผ๋ก ์ ์ฉํ๊ฒ ์ธ ์ ์๋ค.
๋จ์ํ ์ปดํฌ๋ํธ ๋ด์์ ํจ์๋ฅผ ๋ฐ๋ณตํด์ ์์ฑํ์ง ์๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฒ์ด ์๋๋ผ,
React ์ปดํฌ๋ํธ ํจ์ ๋ด์์ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ํจ์๋ฅผ ๋๊ธธ๋
์์ ์ปดํฌ๋ํธ์ prop์ผ๋ก ํจ์๋ฅผ ์ ๋ฌํด์ค๋
์ฌ์คํ์ด ์ผ์ด๋๋ ํ์๊ฐ ์ค์ด๋ค๊ธฐ ๋๋ฌธ์ ์์์น ๋ชปํ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
// App.js
import { useState, useCallback } from "react";
import "./styles.css";
import List from "./List";
export default function App() {
const [input, setInput] = useState(1);
const [light, setLight] = useState(true);
const theme = {
backgroundColor: light ? "White" : "grey",
color: light ? "grey" : "white"
};
// useCallback ์ฌ์ฉ
const getItems = useCallback(() => {
return [input + 10, input + 100];
},[input]);
// ์ต์ ํ ์
// const getItems = () => {
// return [input + 10, input + 100];
// };
const handleChange = (event) => {
if (Number(event.target.value)) {
setInput(Number(event.target.value));
}
};
return (
<>
<div style={theme} className="wall-paper">
<input
type="number"
className="input"
value={input}
onChange={handleChange}
/>
<button
className={(light ? "light" : "dark") + " button"}
onClick={() => setLight((prevLight) => !prevLight)}
>
{light ? "dark mode" : "light mode"}
</button>
<List getItems={getItems} />
</div>
</>
);
}
// List.js
import { useState, useEffect } from "react";
function List({ getItems }) {
/* Initial state of the items */
const [items, setItems] = useState([]);
/* This hook sets the value of items if
getItems object changes */
useEffect(() => {
console.log("์์ดํ
์ ๊ฐ์ ธ์ต๋๋ค.");
setItems(getItems());
}, [getItems]);
/* Maps the items to a list */
return (
<div>
{items.map((item) => (
<div key={item}>{item}</div>
))}
</div>
);
}
export default List;
CSS ์ฝ๋ ์๋ต
๋ถ๋ฅ | useCallback | useMemo |
---|---|---|
์ฌ์ฉ ๋ชฉ์ | ๊ฐ์ ์ฌ์ฌ์ฉ | ํจ์์ ์ฌ์ฌ์ฉ |
ํจ์์ ํธ์ถ์ ๋ง๋๊ฐ? | X | O |
์ต์ ํ ์ฒด๊ฐ ์ ๋ | ์์ | ํผ |
// useMemo ์ฌ์ฉ ๋ฐฉ๋ฒ
const memoizedValue = useMemo(
() => computeExpensiveValue(a, b), [a, b]);
// useCallback ์ฌ์ฉ ๋ฐฉ๋ฒ
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
useCallback(fn, deps)
์ useMemo(() => fn, deps)
์ ๊ฐ๋ค.
Reference:
์ฝ๋์คํ ์ด์ธ
https://ko.reactjs.org/docs/hooks-reference.html#usecallback