메모이제이션으로 React 프로젝트 강화

useMemouseCallback는 메모이제이션을 위한 React 후크입니다. 메모이제이션을 다시 계산할 필요가 없도록 값을 캐싱하는 것으로 생각하십시오. 이렇게 하면 성능이 향상됩니다. useMemouseCallback의 주요 차이점은 useCallback는 메모된 함수(실제로는 '캐시된 함수'를 의미함)를 반환하고 useMemo는 메모된 값을 반환한다는 것입니다. 이 후크를 함께 살펴보겠습니다.

시작하자useMemo

useMemo 사용



사용하는 한 가지 이유useMemo는 종속성 중 하나가 업데이트되지 않는 한 비용이 많이 드는 함수가 다시 렌더링되지 않도록 하는 것입니다.

문제



이 예제에는 모든 렌더링에서 실행되는 비용이 많이 드는 함수가 있습니다.

개수를 변경하거나 할 일을 추가할 때 실행 지연을 알 수 있습니다.

import { useState } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = expensiveCalculation(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;
};

ReactDOM.render(<App />, document.getElementById('root'));


해결책



이 성능 문제를 해결하려면 비용이 많이 드는 함수의 다시 렌더링을 방지하는 방법을 찾아야 합니다. 이를 위해 비싼 함수를 메모라이즈해야 합니다. 이는 비용이 많이 드는 함수 호출을 useMemo 로 래핑하여 수행됩니다.
useMemo 후크는 종속성을 선언하기 위해 두 번째 매개 변수를 허용합니다. 비용이 많이 드는 함수는 종속성이 변경된 경우에만 실행됩니다.

다음 예에서 비용이 많이 드는 함수는 할 일이 추가될 때가 아니라 개수가 변경될 때만 실행됩니다.

import { useState, useMemo } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  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;
};

ReactDOM.render(<App />, document.getElementById('root'));


useCallback을 살펴봅시다!!!

useCallback 사용



useMemo와 useCallback의 주요 차이점은 useCallback은 메모된 함수(실제로는 '캐시된 함수'를 의미함)를 반환하고 useMemo는 메모된 값을 반환한다는 것입니다.

( useCallback 에 대한 코드 예제의 경우 useMemo 에 사용된 정확한 예제를 사용하지만 비용이 많이 드는 함수는 ExpensiveCalc.js 라는 다른 구성 요소에 있습니다.)


import { useState } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);

  const increment = () => {
    setCount((c) => c + 1);
  };

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

  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>
        <ExpensiveCalc count={count} increment={increment}/>
      </div>
    </div>
  );
};




ReactDOM.render(<App />, document.getElementById('root'));



ExpensiveCalc.js
import { memo } from "react";

const ExpensiveCalc = ({ count, increment }) => {
  console.log("child render");
  return (
    <>
      <h2>Count</h2>
      Count: {count}
      <button onClick={increment}>+</button>
    </>
  );
};

export default memo(ExpensiveCalc); //memo will cause React to skip rendering a component if its props have not changed.

좋은 웹페이지 즐겨찾기