[React] useMemo

rsuubinn·2023년 3월 22일
0

React

목록 보기
5/7

✏️ useMemo

그 전에 알아두기

  • 함수형 컴포넌트는 그냥 함수이다. 함수형 컴포넌트는 단지 jsx를 반환하는 함수이다.
  • 컴포넌트가 렌더링 된다는 것은 누군가가 그 컴포넌트(함수)를 호출하여 실행되는 것을 말한다. 함수가 실행될 때 마다 내부에 선언되어 있던 표현식(변수, 또 다른 함수 등)도 매번 다시 선언되어 사용된다.
  • 컴포넌트는 자신의 state가 변경되거나, 부모에게서 받는 props가 변경되었을 때 마다 리렌더링 된다. 심지어 하위 컴포넌트에 최적화 설정을 해주지 않으면 부모에게서 받는 props가 변경되지 않았더라도 리렌더링 되는 것이 기본이다.

렌더링 최적화

기본적으로 react는 부모 컴포넌트로 부터 받는 state, props가 변동될 경우 리렌더링 된다.
하지만 여기에는 분명한 문제가 존재한다.

예를 들어 state, props가 여러가지 일 때
state1, state2, state3이 존재하는 상태에서 state1을 변경시켰는데도 state2, state3도 다시 계산된다면 이것이 과연 좋은 리렌더링 인가?

useMemouseCallback 은 이러한 고민을 가진 개발자들을 위해 탄생했다고 봐도 무방하다.

useMemo 사용법

간단한 예제를 살펴보자.
파일 구성은 App.jsShowState.js 로 구성되어 있다.

// App.js
import React, { useState } from "react";
import ShowState from "./ShowState";

const App = () => {
  const [number, setNumber] = useState(0);
  const [text, setText] = useState("");

  const increaseNumber = () => {
    setNumber((prev) => prev + 1);
  };

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

  const onChangeTextHandler = (e) => {
    setText(e.target.value);
  };

  return (
    <div className="App">
      <div>
        <button onClick={increaseNumber}>+</button>
        <button onClick={decreaseNumber}>-</button>
        <input
          type="text"
          placeholder="Last Name"
          onChange={onChangeTextHandler}
        />
      </div>
      <ShowState number={number} text={text} />
    </div>
  );
};

export default App;

다음은 App으로부터 number와 text를 내려받는 ShowState 컴포넌트 이다.

import React from "react";

const getNumber = (number) => {
  console.log("숫자가 변동되었습니다.");
  return number;
};

const getText = (text) => {
  console.log("글자가 변동되었습니다.");
  return text;
};

const ShowState = ({ number, text }) => {
  const showNumber = getNumber(number);
  const showText = getText(text);

  return (
    <div className="info-wrapper">
      {showNumber} <br />
      {showText}
    </div>
  );
};

export default ShowState;

숫자만 변경하였는데도 위 두 개의 문장이 콘솔에 출력되는 것을 볼 수 있다.
변경하고자 하는 state에 해당되지 않는 함수도 덩달아 실행되니 비효율적이고 낭비라고 생각된다.
이럴 때 useMemo를 사용한다.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

// ShowState.js
import React, { useMemo } from "react";

const getNumber = (number) => {
  console.log("숫자가 변동되었습니다.");
  return number;
};

const getText = (text) => {
  console.log("글자가 변동되었습니다.");
  return text;
};

const ShowState = ({ number, text }) => {
  const showNumber = useMemo(() => getNumber(number), [number]);
  const showText = useMemo(() => getText(text), [text]);

  return (
    <div className="info-wrapper">
      {showNumber} <br />
      {showText}
    </div>
  );
};

export default ShowState;

숫자가 변경될 때는 '숫자가 변동되었습니다.' 라는 출력
글자가 변경될 때는 '글자가 변동되었습니다.' 라는 출력이 나오는 걸 볼 수 있다.

이처럼 memoization 되는 값의 재계산 로직이 expensive한 경우, 즉 복잡한 계산일 경우에 useMemo를 사용하는 것이 추천되고 이런 경우에는 성능상 큰 이점으로 작용한다.

참고

profile
@rsuubinn

0개의 댓글