[React] useMemo Hook으로 성능 최적화 하기

Yeonsu Summer·2023년 11월 5일
0

React

목록 보기
15/15
post-thumbnail
post-custom-banner

프론트엔드 개발자라면 성능 최적화에 신경 쓸 필요가 있다.
리액트는 성능 최적화를 위해 다양한 Hook을 제공한다.

그 중 useMemo 에 대해 알아보자.

📍 개념

리액트에서 컴포넌트가 리렌더링 되면 그 안에 선언된 연산도 다시 계산하게 된다.

useMemoMemoization이라는 뜻으로, 연산 결과를 재사용한다.

즉, 한 번 연산한 결과를 기억하고, 다시 동일한 연산이 필요할 때 기억한 데이터를 반환하는 것이다.

📍 구조 및 사용법

  • useMemouseMemo(연산 정의 함수, deps 배열) 로 이루어져 있다.
    • 연산 정의 함수: 저장하려는 값을 계산하는 함수이다. 다음 렌더링에서 deps가 바뀌지 않으면 동일한 값으로 반환한다. 만약 deps가 변하면 다시 계산된 값을 호출하고 해당 결과를 반환하고 저장한다.
    • deps 배열: 위 함수에서 사용되는 모든 반응형 값의 목록이다. 리액트 내부에서 Object.is 비교를 사용해 각 deps를 이전 값과 비교한다.
  • 리렌더링 사이에서 계산을 저장하기 위해 컴포넌트 최상단에서 호출한다.
import { useMemo } from 'react';

function TodoList({ todos, tab }) {
  // 컴포넌트 최상단에 위치
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab), // 계산 함수
    [todos, tab] // deps 배열
  );
  // ...
}

📍 예제

간단한 Todo List 기능에서 useMemo 을 사용해보자.

import React, { useState } from 'react';

function App() {
  const [todo, setTodo] = useState('');
  const [todoList, setTodoList] = useState([]);

  const onChange = (e) => {
    const { value } = e.target;
    setTodo(value);
  };

  const onSubmit = (e) => {
    e.preventDefault();
    setTodoList([...todoList, todo]);
    setTodo('');
  };

  const getCount = (list) => {
    console.log('What is the number of todo lists?');
    return list.length;
  };

  const count = getCount(todoList);

  return (
    <>
      <h1>Todo List</h1>
      <form onSubmit={onSubmit}>
        <input
          type='text'
          value={todo}
          onChange={onChange}
          placeholder='Enter your to-do'
        />
        <button type='submit'>Save</button>
      </form>
      <div>Total: {count}</div>
      <ul>
        {todoList.map((todo) => (
          <li key={`${todo}`}>{todo}</li>
        ))}
      </ul>
    </>
  );
}

export default App;

위 코드를 직접 사용해보면 막힘 없이 작동하는 것을 볼 수 있다.

하지만 개발자도구를 열고 todo를 입력하면 다음과 같이 getCount 가 계속 호출되는 것을 볼 수 있다.

키보드를 입력할 때마다 렌더링이 되기 때문에 쓸데 없는 getCount 가 불러와지는 것이다.

todo를 저장할 때만 getCount 를 호출하고 싶다면 다음과 같이 수정하면 된다.

const count = useMemo(() => getCount(todoList), [todoList]);

todoList에 값이 들어올 때, 즉 todoList 값이 바뀔 때만 getCount 를 호출한다.

📍 주의사항

무분별하게 사용하면 오히려 성능에 무리가 갈 수 있다.
계산값을 저장하여 재사용하기 때문에 리소스가 낭비될 수 있다.

아래와 같은 상황에서는 useMemo 사용을 지양하는 것이 좋다.

  • 최적화하려는 계산의 비용이 크지 않은 경우.
  • 메모이제이션이 필요한지 확실하지 않은 경우.
  • 메모하고 있는 값이 컴포넌트로 전달되지 않는 경우.
  • 의존성 배열이 너무 자주 변경되는 경우.

React Docs
벨로퍼트와 함께하는 모던 리액트

profile
🍀 an evenful day, life, journey
post-custom-banner

0개의 댓글