useMemo 예제로 알아보기

지현·2022년 12월 29일
0

React

목록 보기
7/11

useMemo 라는 훅이 있는 것은 알았지만 그동안 메모이제이션까지 할 일이 없어서 사용해본적은 없다. 하지만 이번에 useMemo에 대해 배운김에 어떻게 사용하는 것인지 예제를 통해 정리해보려한다.

해당 예제는 일부러 무거운 연산을 실행함과 동시에 부하를 일으키면서 숫자와 텍스트를 변경하는 코드이다.

App.jsx

App.jsx에서는 화면이 렌더링 될 때마다 heavyCalc 함수를 실행하며 number와 text를 바꿔주는 함수핸들러, 그리고 바뀐 number와 text값을 보여주는 ShowState 컴포넌트가 있다.

import React, { useState,useMemo } from 'react';
import ShowState from './ShowState';

export default function App() {
  const [number, setNumber] = useState(0);
  const [text, setText] = useState('');

  // 일부러 과도한 연산을 하는 함수
  function heavyCalc() {
    let s = 0;
    for (let i = 0; i < 1000000000; i++) {
      s += i;
    }
    return s;
  }
  let calc = heavyCalc();

  //number 값 바꿔주는 함수
  const increaseNum = () => {
    setNumber((prev) => prev + 1);
  };

  const decreaseNum = () => {
    setNumber((prev) => prev - 1);
  };

  //text값 바꿔주는 함수
  const handleText = (e) => {
    setText(e.target.value);
  };

  return (
    <>
      <h1>엄청난 연산값</h1>
      <p>{calc}</p>
      <h2>숫자바꾸기</h2>
      <button onClick={increaseNum}>+</button>
      <button onClick={decreaseNum}>-</button>
      <h2>글자바꾸기</h2>
      <input type="text" onChange={handleText} />
      <ShowState number={number} text={text} />
    </>
  );
}

ShowState.jsx

ShowState 컴포넌트에서는 App.jsx에서 바꾼 값들을 출력해주고 값이 바뀔 때 마다 '숫자가 변경되었습니다.' 와 '글자가 변경되었습니다.' 라는 문구를 console에 출력한다.

import React, { useMemo } from 'react';

export default function ShowState({ number, text }) {
  const consoleNumber = (number) => {
    console.log('숫자가 변경되었습니다.');
    return number;
  };

  const consoleText = (text) => {
    console.log('글자가 변경되었습니다.');
    return text;
  };

  const showNum = consoleNumber(number);
  const showText = consoleText(text);


  return (
    <div>
      <p> 숫자 : {showNum}</p>
      <p> 글자 : {showText}</p>
    </div>
  );
}

위 예제를 실행한 모습

+- 버튼을 누르면 숫자 값이 바뀌고, input창에 글자를 입력하면 입력하는대로 글자가 출력되는 것을 알 수 있다.

하지만 이를 실행해보면 매우 느리게 실행된다. 이는 숫자나 글자를 바꿈으로써 화면이 리렌더링될 때마다 heavyCalc 함수가 실행되기 때문..

useMemo 를 사용해보자!

heavyCalc 함수의 결과값인 calc는 계속 같은 값을 가지기 때문에 매번 새로 연산을 진행할 필요가 없다. 이 때 쓸 수 있는 것이 이전에 이미 계산한 값을 재사용할 수 있도록 도와주는 useMemo 인 것이다.

App.jsx의 heavyCalc 함수 실행문을 이렇게 useMemo를 이용하여 감싼다면?

  const calc = useMemo(() => {
    return heavyCalc();
  }, []);

useMemo를 통해 이전에 계산했던 499999999067109000 라는 값을 계속 재사용하여 화면에 출력해주기 때문에 같은 계산을 위해 부하를 일으키지 않는 것을 확인할 수 있다.

이처럼 useMemo는 렌더링이 발생했을 때, 이전 렌더링과 현재 렌더링 사이에 값이 동일하다면 다시 함수를 호출을 하여 결과를 구하는 대신, 기존에 메모리에 저장해두었던 값을 그대로 사용하도록 도와주는 것이다.

useMemo로 감싼 후 다시 값을 변경해보면?


increaseNum 함수를 두번 실행하여 숫자가 2가 되었다!


근데 문제가 있는데?

하지만 콘솔창을 확인하니 increaseNum 함수가 실행될 때마다 Text값을 바꾸지 않았음에도 '글자가 변경되었습니다.' 라는 문구가 같이 출력된다.

변경하고자 하는 state에 해당되지 않는 함수가 실행될 필요는 없기 때문에 useMemo를 사용하여 숫자가 변경될 경우와 글자가 변경될 경우에만 console 출력을 하도록 바꿔보자.

  const showNum = useMemo(() => consoleNumber(number), [number]);
  const showText = useMemo(() => consoleText(text), [text]);

showNum과 showText 값을 이렇게 변경하여 number 값이 변했을때만 consoleNumber 함수가, text값이 변했을때만 consoleText함수가 실행되도록 했다.

아까처럼 increasNum 을 두번 실행했을때 text의 값을 변경하지 않았으므로 consoleNumber 함수만 두 번 실행되는 것을 볼 수 있다.

그 상태에서 text의 값을 4번 변경하니 consoleText함수도 4번 실행된다.

즉, 숫자가 변경될 때는 '숫자가 변동되었습니다.' 라는 console만 뜨고
글자가 변경될 때는 '글자가 변동되었습니다.' 라는 console만 뜨게 되는 것이다.

결론

useMemo 를 사용하면 메모이제이션 기법을 이용하여 이전에 저장되었던 결과를 다시 가져와 재사용할 수 있기 때문에 코드최적화에 도움을 줄 수 있다. 언젠간 사용해볼 날이 오길..

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

As individuals become more mybkexperience health-conscious and environmentally aware, there has been a growing demand for alternative food options.
https://mydreamangels.mn.co/posts/39293851

답글 달기