React useMemo를 사용하는 이유

최문경·2022년 1월 20일
0

useCallback을 사용하는 이유에서 useCallback은 react가 함수를 기억하도록해서 해당 함수를 props로 전달받는 컴포넌트들의 불필요한 재실행을 막도록한다고 했다.

이와 비슷하게 useMemo는 react가 값을 기억하도록 한다. 자세하게는 dependencies가 변할 때만 값을 다시 생성한다. 따라서 불필요한 연산 또는 컴포넌트 재실행을 방지할 수 있다.

만약 아래와 같이 배열을 넘겨주는 컴포넌트와 그 배열을 받아서 정렬하는 컴포넌트가 있다고 해보자.

// App.js
import { useState } from 'react';
import List from './List';

function App() {
  console.log('App Running');

  const [listTitle, setListTitle] = useState('My List');

  const changeTitleHandler = () => {
    setListTitle('New Title');
  };
  
  const listItems = [5, 2, 3, 1, 4];

  return (
    <div className='App'>
      <List title={listTitle} items={listItems} />
      <button onClick={changeTitleHandler}>Change List Title</button>
    </div>
  );
}

export default App;
// List.js
const List = (props) => {
  console.log('List Running');

  const sortedList = items.sort((a, b) => a - b);

  return (
    <div>
      <h2>{props.title}</h2>
      <ul>
        {sortedList.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

export default List;

이처럼 배열의 값이 변하지 않는 상황인데 컴포넌트가 재실행되면서 (버튼 클릭) 배열도 다시 정렬된다면 배열의 크기가 커질수록 비효율적일 것이다.

따라서 아래와 같이 listItems에 useMemo를 사용해 값을 저장해서 List컴포넌트에게 같은 listItems를 전달해주고 List컴포넌트에서는 items의 값이 변할 때만 정렬을 하도록 useMemo를 사용한다면 불필요한 연산(여기서는 정렬)을 방지할 수 있다.

// App.js
import { useMemo, useState } from 'react';
import List from './List';

function App() {
  console.log('App Running');

  const [listTitle, setListTitle] = useState('My List');

  const changeTitleHandler = () => {
    setListTitle('New Title');
  };

  const listItems = useMemo(() => [5, 2, 3, 1, 4], []);

  return (
    <div className='App'>
      <List title={listTitle} items={listItems} />
      <button onClick={changeTitleHandler}>Change List Title</button>
    </div>
  );
}

export default App;
// List.js
import { useMemo } from 'react';

const List = (props) => {
  console.log('List Running');

  const { items } = props;

  const sortedList = useMemo(() => {
    console.log('Sorted');
    return items.sort((a, b) => a - b);
  }, [items]);

  return (
    <div>
      <h2>{props.title}</h2>
      <ul>
        {sortedList.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

export default List;

profile
프론트엔드 공부하고 있습니다!

0개의 댓글