React - useMemo와 React.memo(Memoization)

uk·2023년 2월 20일
1

React

목록 보기
10/17

useMemo

useMemo는 컴포넌트의 성능을 최적화하기 위한 React Hooks 중 하나이며 연산의 결과값을 재사용하기위해 사용된다.

React에서 화면의 일부분만 업데이트 되어도 컴포넌트를 re-rendering 하기 때문에 값을 재사용하여 불필요한 re-renering을 방지하기 위해 사용된다.

const Calculator = ({ val }) => {
  const result = calculate(val);

  return (
    <>
      <div>
		{result}
      </div>
    </>
  );
}

위 코드는 props로 넘어온 val 값을 calculate라는 함수에 인자로 넘겨서 result 값을 구한 후 <div> 엘리먼트로 출력하고있다.

만약 calculate가 복잡한 연산을 수행하는 함수라서 계산된 값을 반환하는 데 몇 초 이상 걸릴 경우 컴포넌트가 렌더링 될 때마다 이 함수를 계속해서 호출할 것이고 그 때마다 몇 초 이상의 시간이 소요되어 지연이 발생해 렌더링에 영향을 미칠 것이다.

import { useMemo } from 'react';

const Calculator = ({ val }) => {
  const result = useMemo(() => calculate(val), [val]);

  return (
    <>
      <div>
		{result}
      </div>
    </>
  );
}

val을 인자로 받는 Calculator 컴포넌트가 렌더링 될 때 val 값의 변경이 일어나지 않을 경우 이 값을 어딘가에 저장 해뒀다가 다시 꺼내쓴다면 굳이 calculate 함수를 호출할 필요가 없다.

이때 useMemo를 사용하면 이전에 구축된 렌더링과 새로 구축되는 렌더링을 비교해 val 값이 동일할 경우 이전 렌더링의 val 값을 재사용 할 수 있다.

useMemo에서 Memo는 Memoization을 뜻한다.


Memoization

메모이제이션이란 연산의 결과값을 메모리에 저장해 두고 동일한 입력이 들어오거나 이전 값과 동일할 경우 값을 재사용 하는 기법이다. 메모이제이션을 이용하면 중복 연산을 하지 않기 때문에 앱의 성능을 최적화할 수 있다.

하지만 메모리에 값을 저장하기 때문에 리렌더링이 자주 발생하지 않는다면 굳이 사용할 필요는 없다. 무분별하게 사용된다면 불필요한 값들까지 모두 메모리에 저장되어 오히려 성능이 떨어지게 되므로 필요한 경우에만 적절히 사용해야 한다.


useMemo 예시

import { useState, useMemo } from 'react';

const App = () => {
  const [text, setText] = useState('');
  const [num1, setNum1] = useState(0);
  const [num2, setNum2] = useState(0);

  const plus = (num1, num2) => {
    console.log('re-rendering');
    return Number(num1) + Number(num2);
  };

  // const result = add(val1, val2);
  const result = useMemo(() => plus(num1, num2), [num1, num2]);
  
  return (
    <>
      <input
        className="text"
        value={text}
        type="text"
        onChange={(e) => setText(e.target.value)}
      />

      <input
        className="num"
        value={num1}
        type="number"
        onChange={(e) => setNum1(Number(e.target.value))}
      />

      <input
        className="num"
        value={num2}
        type="number"
        onChange={(e) => setNum2(Number(e.target.value))}
      />

      <div>{result}</div>
    </>
  );
}

export default App;

위 코드는 text와 number를 입력받고 두 number의 합을 출력하는 코드이며 컴포넌트에서 연산 로직에 영향을 주는 값은 num1, num2 이다. 하지만 text 입력 시 컴포넌트가 리렌더링 되고 plus 함수가 새로 생성되어 're-rendering'이 출력된다.

이때 plus 함수에 useMemo를 사용하면 메모이제이션된 값을 재사용하기 때문에 text 입력 시 불필요한 리렌더링이 발생하여 plus 함수의 생성을 방지할 수 있고 컴포넌트를 최적화 시킬 수 있다.

useMemo를 사용하지 않을 경우 "test"를 포함하여 총 9번의 re-rendering이 발생하게 된다.


React.memo

React.memo는 React에서 제공하는 고차 컴포넌트(HOC, Higher-Order Components)이다. HOC는 컴포넌트를 인자로 받아 UI나 기능은 동일하지만 최적화된 새로운 컴포넌트를 반환해주는 함수이다.

부모 컴포넌트가 렌더링되면 모든 자식 컴포넌트들도 렌더링된다. 이때 자식 컴포넌트가 React.memo를 통해 최적화 되어있다면 Prop Check를 진행하고 props의 변화가 있을 경우 렌더링을 진행, 변화가 없다면 새로 렌더링을 하는 것이 아닌 기존의 렌더링된 결과를 재사용한다.

즉 React.memo는 자식 컴포넌트의 props가 변하지 않아 매번 같은 결과를 보여줄 경우 불필요한 렌더링을 방지하여 컴포넌트의 성능을 최적화하기 위해 사용된다.


사용 방법

import { memo } from 'react';

react로부터 memo를 불러온다.

// props(val1, val2의 값)가 변경되지 않으면 렌더링이 발생하지 않음
const ChildComponent = {{ val1, val2 }} = > {
  ...
};

// memo 함수는 ChildComponent를 인자로 받아서 최적화된 컴포넌트를 반환
export default memo(ChildComponent);

최적화하고 싶은 컴포넌트를 불러온 memo 함수로 감싸준다.


React.memo를 사용하면 좋은 경우

  1. 컴포넌트가 동일한 props로 잦은 렌더링이 발생할 경우
  2. 컴포넌트가 렌더링될 때마다 복잡한 로직을 처리할 경우

React.memo 사용 시 주의할 점

React.memo는 오직 props 변화에만(prop Check) 의존하는 최적화 방법이다. 컴포넌트가 useState, useReducer, useContext와 같은 상태와 관련된 Hook을 사용하면 props에 변화가 없더라도 state나 context가 변경될 때마다 리렌더링이 발생한다.


const obj = useMemo(() => {
  return {
    name: 'navi',
    age: '5',
  };
}, []);

props가 객체 형식일 경우 컴포넌트가 렌더링 될 때마다 참조하는 메모리의 주소값이 달라지기 때문에 props가 변경되었다고 판단하고 컴포넌트를 렌더링 시킨다. 그러므로 객체 형식의 경우 useMemo를 통해 메모이제이션하면 할당되어 있는 메모리 주소가 변하지 않으므로 최적화가 가능하다.

함수도 객체이기 때문에 useCallback을 사용한다.


useMemo와 React.memo의 차이점

  1. useMemo는 React Hook 이고 React.memo는 HOC 이다.

  2. React.memo는 클래스형 컴포넌트와 함수형 컴포넌트 모두 사용 가능하지만 useMemo는 함수형 컴포넌트 안에서만 사용 가능하다.

  3. useMemo는 특정 값을 재사용하기 위해 사용되고 React.memo는 컴포넌트를 재사용하기 위해 사용된다.

profile
주니어 프론트엔드 개발자 uk입니다.

0개의 댓글