๋ ๋๋ง ์ต์ ํ๋ฅผ ์ํ Hook์ธ
useMemo์ useCallback์ ๋ํด ์์๋ณด์๐จ
useMemo
: ๊ฐ์ ์ฌ์ฌ์ฉ์ ์ํด ์ฌ์ฉํ๋ Hook
useCallback
: ํจ์์ ์ฌ์ฌ์ฉ์ ์ํด ์ฌ์ฉํ๋ Hook
์๋ ์ฝ๋์์ ๋ง์ฝ Calculator๊ฐ ๋ณต์กํ ์ฐ์ฐ์ ํ๋ ํจ์๋ผ์
๊ณ์ฐ๋ ๊ฐ์ ๋ฐํํ๋ ๊ฒ ์ค๋ ๊ฑธ๋ฆฌ๋ฉฐ, props๋ก ๋ฐ์ value๊ฐ์ด
๊ณ์ ๋ฐ๋๋ ๊ฒ ์๋๋ผ๋ฉด, useMemo๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ ํ๋ฅผ ํ ์ ์๋ค.
useMemo๋ฅผ ์ฌ์ฉํ๋ฉด value๊ฐ์ด ์ด์ ๊ณผ ๋์ผํ ๊ฒฝ์ฐ์๋
์ด์ ๋ ๋๋ง์ value๊ฐ์ ๊ทธ๋๋ก ์ฌํ์ฉํ ์ ์๊ฒ ๋๋ค.
(์ด์ ๊ฐ๊ณผ ๊ฐ์๋ฐ, ๊ณ์ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ํจ์๋ฅผ ๊ตณ์ด ๋ค์ ํธ์ถํ ํ์๊ฐ ์๊ฒ ๋จ)
/* useMemo ๊ฐ์ ธ์ค๊ธฐ */
import { useMemo } from "react";
function Calculator({ value }) {
const result = useMemo(() => calculate(value), [value]);
return <>
<div>
{result}
</div>
</>;
}
๊ฐ์ ํจ์ ๋ด์ ์๋ ์ฒซ ๋ฒ์งธ input์ฐฝ์ ์ด๋ฆ์ ์
๋ ฅํ๋ฉด
๋ฆฌ๋ ๋๋ง์ด ๋์ด์ addํจ์๋ ์ฌํธ์ถ์ด ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด๋ useMemo๋ฅผ ์ฌ์ฉํ๋ฉด val1, val2์ ๊ฐ์ด ๋ฐ๋ ๋์๋ง
addํจ์๊ฐ ํธ์ถ๋์ด ๋ถํ์ํ ๋ ๋๋ง์ ๋ง์์ค๋ค.
import React, { useState, useMemo } from "react";
const add = (num1, num2) => {
console.log("์ซ์๊ฐ ๋ค์ด์ต๋๋ค.");
return Number(num1) + Number(num2);
};
export default function App() {
const [name, setName] = useState("");
const [val1, setVal1] = useState(0);
const [val2, setVal2] = useState(0);
const answer = useMemo(() => add(val1, val2), [val1, val2]);
// const answer = add(val1, val2);
console.log(answer);
return (
<div>
<input
className="name-input"
placeholder="์ด๋ฆ์ ์
๋ ฅํด์ฃผ์ธ์"
value={name}
type="text"
onChange={(e) => setName(e.target.value)}
/>
<input
className="value-input"
placeholder="์ซ์๋ฅผ ์
๋ ฅํด์ฃผ์ธ์"
value={val1}
type="number"
onChange={(e) => setVal1(Number(e.target.value))}
/>
<input
className="value-input"
placeholder="์ซ์๋ฅผ ์
๋ ฅํด์ฃผ์ธ์"
value={val2}
type="number"
onChange={(e) => setVal2(Number(e.target.value))}
/>
<div>{answer}</div>
</div>
);
}
์ฌ์ฉ๋ฒ์ useMemo์ ๋น์ทํ๋ค.
๋ค๋ฅธ ์ ์ด ์๋ค๋ฉด ๊ฐ์ด ์๋๋ผ ํจ์๋ฅผ ์ฌํ์ฉํ๋ค๋ ๊ฒ.
useCallback์ ์ฌ์ฉํ๋ฉด ๊ทธ ํจ์๊ฐ ์์กดํ๋ ๊ฐ๋ค์ด
๋ฐ๋์ง ์๋ ํ ๊ธฐ์กด ํจ์๋ฅผ ๊ณ์ํด์ ๋ฐํํ๋ค.
But, ์ด๋ ๊ฒ ๋จ์ํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด useCallback์
์ฌ์ฉํ๋ฉด, ํฐ ์๋ฏธ๊ฐ ์๊ฑฐ๋ ์คํ๋ ค ๋ ์ํด์ผ ์ ์๋ค.
โ๊ทธ๋ผ ์ธ์ ์ฌ์ฉํ๋ ๊ฒ ์ข์๊น?
useCallback์ ์ด์ฉํด ํจ์ ์์ฒด๋ฅผ ์ ์ฅํด์ ๋ค์ ์ฌ์ฉํ๋ฉด,
ํจ์์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ์ ์ ์ฅํ๋ค๊ฐ ๋ค์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ๋ค.
๋ฐ๋ผ์ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ๋๊ธฐ๊ฑฐ๋ ์์ ์ปดํฌ๋ํธ์
props๋ก ๋๊ธธ ๋ ์์์น ๋ชปํ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ๋ง์ ์ ์๋ค.
/* useCallback ๊ฐ์ ธ์ค๊ธฐ */
import React, { useCallback } from "react";
function Calculator({ x, y }) {
// x์ y๊ฐ์ด ๋์ผํ๋ค๋ฉด ๋ค์ ๋ ๋๋ง ๋ ์ด ํจ์๋ฅผ ๋ค์ ์ฌ์ฉ
const add = useCallback(() => x + y, [x, y]);
return <>
<div>
{add()}
</div>
</>;
}
๋คํฌ ๋ชจ๋๋ฅผ ๋๋ ์ ๋ getItemsํจ์๊ฐ ๊ณ์ ํธ์ถ๋ ํ์๋ ์๋ค.
๋ํ ์์์๊ฒ๋ getItems๋ฅผ ๋๊ฒจ์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์,
useCallback์ ์ฌ์ฉํ๋ฉด ๋ถํ์ํ ๋ ๋๋ง์ ๋ง์์ค ์ ์๋ค.
import { useState, useCallback } from "react";
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"
};
const getItems = useCallback(() => {
return [input + 10, input + 100];
}, [input]);
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>
</>
);
}
-------
/* ์์ ์ปดํฌ๋ํธ */
import { useState, useEffect } from "react";
function List({ getItems }) {
const [items, setItems] = useState([]);
useEffect(() => {
console.log("์์ดํ
์ ๊ฐ์ ธ์ต๋๋ค.");
setItems(getItems());
}, [getItems]);
return (
<div>
{items.map((item) => (
<div key={item}>{item}</div>
))}
</div>
);
}
export default List;
React์์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ์ฌ์ฉ๋๋ HOC(Higher Order Component)์ด๋ค.
React.memo๋ ์ปดํฌ๋ํธ์ props๊ฐ ๋ณ๊ฒฝ๋์์ ๋๋ง ๋ค์ ๋ ๋๋ง ํ๋ค.
(useState, useReducer, useContext ํ
์ ์ฌ์ฉํ๋ค๋ฉด,
state๋ context๊ฐ ๋ณํ ๋ ๋ค์ ๋ ๋๋ง์ด ๋๋ค.)
import React from "react";
const Child = React.memo((props) => {
/* props๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋๋ง */
})
๐ React(๊ณต์๋ฌธ์1) - useMemo ๏ผ useCallback ๏ผ React.memo
๐ React(๊ณต์๋ฌธ์2) - useMemo ๏ผ useCallback