Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

useMemo 훅에 대하여 본문

🎨 프론트엔드/React.js

useMemo 훅에 대하여

Chamming2 2020. 12. 30. 15:44

useMemo 훅은 useStateuseEffect에 비해서는 존재감이 다소 떨어지지만 강력한 기능을 탑재하고 있습니다.

바로 메모이제이션을 구현해 함수의 중복 동작을 막아 성능을 향상시킬 수 있는데, 한번 사용 방법을 살펴보도록 하겠습니다.

 

[useMemo 훅의 기본 형태]

import React, {useMemo} from 'react'

const memoizedValue = useMemo(() => {
    return (수행할 동작 (주로 시간이 오래 걸리는));
}, [의존값]);

리액트 컴포넌트는 재렌더링될때마다 컴포넌트 내의 모든 함수를 다시 호출하지만, useMemo를 사용하면 의존값으로 주어진 값이 변경될 때만 특정 함수를 호출할 수 있습니다.

import React, { useState, useMemo, useEffect } from "react";

function UseMemo() {
  const [number, setNumber] = useState(0);
  const [dark, setDark] = useState(false);

  const doubleNumber = useMemo(() => {
    return slowFunction(number);
  }, [number]);

  const themeStyles = useMemo(() => {
    return {
      backgroundColor: dark ? "black" : "white",
      color: dark ? "white" : "black",
    };
  }, [dark]);

  useEffect(() => {
    console.log("theme changed");
  }, [themeStyles]);

  return (
    <div>
      <input
        type="number"
        value={number}
        onChange={(e) => setNumber(parseInt(e.target.value))}
      ></input>
      <button onClick={() => setDark((prevDark) => !prevDark)}>
        테마 변경하기
      </button>
      <div style={themeStyles}>{doubleNumber}</div>
    </div>
  );
}

function slowFunction(num) {
  console.log("느린 작업을 수행합니다...");
  for (let i = 0; i <= 1000000000; i++) {}
  return num * 2;
}

export default UseMemo;

코드가 다소 길어 동작을 설명하면 다음과 같습니다.

  • 숫자(상태값)를 임의로 변경할 수 있는 입력창이 있다.
  • 숫자를 변경하면 시간이 오래 걸리는 slowFunction()이라는 함수가 호출된다.
  • 테마 변경을 클릭하면 배경(상태값)색이 변한다. (다크 모드)

얼핏 보면 별 문제가 없는 것 같지만, 중요한 문제가 하나 숨어 있습니다.

원래 의도대로라면 slowFunction() 함수는 숫자를 변경할 때만 호출되어야 하지만 테마를 변경할때도 dark 라는 상태값이 변함으로써 slowFunction() 함수가 호출되고 있어 렌더링이 많이 지연되고 있는 상태입니다.

 

바로 이럴 때 useMemo를 사용할 수 있는데, number 상태값을 의존값으로 삼아 숫자를 변경할 때만 slowFunction()이 호출되도록 할 수 있습니다!

import React, { useState, useMemo, useEffect } from "react";

function UseMemo() {
  const [number, setNumber] = useState(0);
  const [dark, setDark] = useState(false);

  const doubleNumber = useMemo(() => {
    return slowFunction(number);
  }, [number]);

  const themeStyles = {
    backgroundColor: dark ? "black" : "white",
    color: dark ? "white" : "black",
  };

  useEffect(() => {
    console.log("theme changed");
  }, [themeStyles]);

  return (
    <div>
      <input
        type="number"
        value={number}
        onChange={(e) => setNumber(parseInt(e.target.value))}
      ></input>
      <button onClick={() => setDark((prevDark) => !prevDark)}>
        테마 변경하기
      </button>
      <div style={themeStyles}>{doubleNumber}</div>
    </div>
  );
}

function slowFunction(num) {
  console.log("느린 작업을 수행합니다...");
  for (let i = 0; i <= 1000000000; i++) {}
  return num * 2;
}

export default UseMemo;

이제 의도했던 대로 숫자값이 변할때만 slowFunction()이 호출되는 것을 확인할 수 있습니다.

하지만 메모이제이션의 특성상 기억할 값을 메모리 한켠에 따로 저장하게 되는데, useMemo 훅을 너무 남발하다가는 페이지 응답 속도가 느려지는 등 부작용이 있을 수도 있으니 적재적소에 사용하도록 하는 것을 권장드립니다. 😆

반응형

'🎨 프론트엔드 > React.js' 카테고리의 다른 글

useContext 훅에 대하여  (0) 2021.01.05
useRef 훅에 대하여  (1) 2021.01.01
Portal 사용하기  (0) 2020.12.28
useEffect 훅에 대하여  (1) 2020.12.28
useState 훅에 대하여  (0) 2020.12.28
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆