FA/React

20221102 React Hooks - useMemo, useCallback

๐Ÿ๐Ÿ๋ฆผ 2022. 11. 2. 19:55

Hook์˜ ๊ทœ์น™

  • React ํ•จ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ(๋ฐ˜๋“œ์‹œ Functional Component ์•ˆ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•จ)
  • ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ
  • ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ ๋ชป ์”€

useMemo, useCallback

์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

useMemo๋Š” ํŠน์ • ๊ฒฐ๊ณผ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉ

useCallback์€ ํŠน์ • ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ

 

memoization (๋ฉ”๋ชจ์ด์ œ์ด์…˜)

์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์ด์ด ๋™์ผํ•œ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•  ๋•Œ, ์ด์ „์— ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•จ์œผ๋กœ์จ ๋™์ผํ•œ ๊ณ„์‚ฐ์˜ ๋ฐ˜๋ณต ์ˆ˜ํ–‰์„ ์ œ๊ฑฐํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์†๋„๋ฅผ ๋น ๋ฅด๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ๋™์  ๊ณ„ํš๋ฒ•์˜ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

- ์ž์ฃผ ํ•„์š”ํ•œ ๊ฐ’์„ ์บ์‹ฑํ•ด ๋‘์–ด์„œ ๊ทธ ๊ฐ’์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์บ์‹œ๋ฅผ ๊บผ๋‚ด ์“ฐ๋Š” ๊ฒƒ

 

useMemo

  • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง์ด ๋  ๋•Œ > Component ํ•จ์ˆ˜ ํ˜ธ์ถœ > ๋ชจ๋“  ๋‚ด๋ถ€ ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™”
  • memoization์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ Œ๋”๋ง ํ• ๋•Œ ์žฌ์‚ฌ์šฉํ•จ >  ์ตœ์ ํ™”๋Š” ๋ชจ๋“  ๋ Œ๋”๋ง ์‹œ์˜ ๊ณ ๋น„์šฉ ๊ณ„์‚ฐ์„ ๋ฐฉ์ง€
  • useMemo๋กœ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๋Š” ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰
  • ์ฝœ๋ฐฑํ•จ์ˆ˜์™€, ์˜์กด์„ฑ๋ฐฐ์—ด[]์„ ๊ฐ€์ง
  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ '๊ฐ’'์„ ๋ฐ˜ํ™˜
import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  //useMemo ์ฒซ๋ฒˆ์งธ ์ธ์ž ์ฝœ๋ฐฑํ•จ์ˆ˜, ๋‘๋ฒˆ์งธ์ธ์ž ์˜์กด์„ฑ๋ฐฐ์—ด []
  const calculation = useMemo(() => expensiveCalculation(count), [count]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

 

 

useCallback

  • useMemo์™€ ์œ ์‚ฌํ•จ ๋Œ€์‹  ์ธ์ž๋กœ ์ „๋‹ฌํ•œ ์ฝœ๋ฐฑํ•จ์ˆ˜ ๊ทธ ์ž์ฒด๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•จ
  • ์ฝœ๋ฐฑํ•จ์ˆ˜์™€, ์˜์กด์„ฑ๋ฐฐ์—ด[]์„ ๊ฐ€์ง
  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ 'ํ•จ์ˆ˜'๋ฅผ ๋ฐ˜ํ™˜

ํ•จ์ˆ˜๋ฅผ ๋งค๋ฒˆ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋””ํŽœ๋˜์‹œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑ

const handleLoad = useCallback((option) => {
  // ...
}, [dep1, dep2, dep3, ...]);

 

 

์ฐธ๊ณ  ๋ฐ ์ถœ์ฒ˜

https://ko.wikipedia.org/wiki/%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98

 

๋ฉ”๋ชจ์ด์ œ์ด์…˜ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „. ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์€ ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ผํ•œ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•  ๋•Œ, ์ด์ „์— ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•จ์œผ๋กœ์จ ๋™์ผํ•œ ๊ณ„์‚ฐ์˜ ๋ฐ˜๋ณต ์ˆ˜ํ–‰์„ ์ œ๊ฑฐํ•˜์—ฌ

ko.wikipedia.org

https://ko.reactjs.org/docs/hooks-reference.html#usememo

https://www.w3schools.com/react/react_usememo.asp

https://ko.reactjs.org/docs/hooks-reference.html#usecallback

https://www.w3schools.com/react/react_usecallback.asp