본문 바로가기

React

React / React + Typescript / useMemo에 대하여...

useMemo

useMemo는 비용이 큰 연산에 대한 결과를 저장해두고, 이 저장된 값을 반환하는 훅이다. 흔히 리액트에서 최적화를 떠올릴 때 가장 먼저 언급되는 훅이 바로 useMemo다.

 

메모이제이션을 사용하지 않는 경우 예시

메모이제이션을 사용하지 않는 경우 많은 연산을 하는 컴포넌트가 의존되는 값의 변화가 없음에도 불구하고 리렌더링되어 성능저하를 일으킬 수 있다.

ExpensiveComponent는 많은 연산을 진행하는 컴포넌트라 가정하여 사용한다. UseMemo는 ExpensiveComponent를 사용하는 컴포넌트이다.

 

 

ExpensiveComponent.tsx

import React, { useEffect } from 'react';

interface Props {
  value: number | undefined;
}

const ExpensiveComponent: React.FC<Props> = ({ value }) => {
  useEffect(() => {
    console.log('rendering!');
  });

  return <span>{value}</span>;
};

export default ExpensiveComponent;

 

 

UseMemo.tsx

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

type ChangeEvent = React.ChangeEvent<HTMLInputElement>;

function UseMemo() {
  const [value, setValue] = useState<number | undefined>(10);
  const [, triggerRendering] = useState<boolean | undefined>(false);

  function handleChange(e: ChangeEvent) {
    setValue(Number(e.target.value));
  }

  function handleClick() {
    triggerRendering((prev) => !prev);
  }

  return (
    <>
      <input value={value} onChange={handleChange} />
      <button onClick={handleClick}>렌더링 발생!</button>
      <ExpensiveComponent value={value} />
    </>
  );
}

export default UseMemo;

 

출력

 

 

value 값의 변화가 없는 경우에도 리렌더링을 강제로 발생시킬 시 ExpensiveComponent는 리렌더링 된다.

 

메모이제이션을 통한 리렌더링 방지

 

ExpensiveComponent를 React.memo로 감싸주며 메모이제이션을 도입할 수 있다. 자동으로 Props를 의존성 요소로 반영하여 메모이제이션을 진행한다.

 

import React, { useEffect } from 'react';

interface Props {
  value: number | undefined;
}

const ExpensiveComponent: React.FC<Props> = ({ value }) => {
  useEffect(() => {
    console.log('rendering!');
  });

  return <span>{value}</span>;
};

export default React.memo(ExpensiveComponent);

 

출력