useMemo 이해하기

2023. 11. 19. 12:17·⭐FE

✅useMemo란?

useMemo는 재렌더링 사이에 계산결과 값을 캐싱하는 hook이다.useMemo를 사용하면 재 렌더링 시 캐싱된 값을 그대로 사용하므로 불필요한 계산과정을 스킵하여 컴포넌트 렌더링 시간을 단축시킬 수 있다. 그렇다고 무조건 useMemo를 사용해야 되냐? 그것은 아니다. 오히려 대부분의 곳에서 useMemo는 오히려 불필요하고 특정한 상황에서 사용 시 성능상 이점을 가져 갈 수 있다. 

 

✅useMemo 예시 코드

만약 `filterTodos(todos,tab)` 함수가 2초가 걸린다고 가정해보자 그럼 아래와같이 useMemo 없이 코드가 쓰였을때 `TodoList` 컴포넌트가 재랜더링이 될 때마다 `filterTodos(todos, tab)` 가 실행되면서 TodoList 컴포넌트가 렌더링되는데 최소 2초가 걸린다.

function TodoList({ todos, tab }) {
  const visibleTodos = filterTodos(todos, tab) 
  ....

}

그런데 만약 useMemo를 이용해서 `filterTodos(todos, tab)` 계산결과의 값을 메모이제이션하면 특정상황 ( 디펜던시 리스트의 todos와 tab의 값이 변화할 때 )을 제외하곤 재렌더링 시에 `filterTodos(todos,tab)` 연산을 하지않고 메모이제이션된 값(캐싱된 값)을 이용하기 때문에 `TodoList` 컴포넌트의 렌더링 시간을 단축시킬 수 있다. 

import { useMemo } from 'react';

function TodoList({ todos, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab] 
    // 1.todos와 tab중 하나라도 변경될 시 ()=> filterTodos(todos,tab) 실행
    // 2.함수 실행으로 return된 값을 visibleTodos에 저장
    // 만약 의존성 리스트들이 변하지 않는다면 재렌더링 사이에 해당 함수는 실행되지 않고
    // 2에서 캐싱된 값을 그대로 이용
  );
  
  ...
}

 

✅dependencies의 값 비교는 어떤식으로 할까?

useMemo 에서는 dependency array에 존재하는 값들의 변화를 자바스크립트의 Object.is()를 이용하여 확인한다. 예를들어 위 예시코드에서 보면 dependency array에 todos와 tab이 있는데 Object.is(이전 todos, 다음 todos) 의 값이 true이면 todos가 변하지 않았다고 판단한다. 주의 할 점은 Object.is는 얕은 비교를 하는 함수이기 때문에 참조형 타입인 객체를 dependency array 에 사용할 시 주의해야 한다. 

 

✅useMemo 언제 사용할까?

사실 일반적으로 useMemo를 사용할 만큼 비용이 큰 연산을 사용할 일이 개발을 하다보면 많진 않다. 그럼 언제 사용할까? 라는 생각이 들텐데 이에 대한 기준을 react 공식 홈페이지에서 아래와 같이 가이드하고 있었다. ( 사용 case에 대한 자세한 내용을 확인하려면 공홈 - useMemo 를 알아보자 )

  • useMemo에 입력하는 계산이 눈에 띄게 느리고 종속성이 거의 변경되지 않는 경우
  • memo로 감싸진 컴포넌트에 prop로 값을 전달할 경우 ( 메모이제이션을 사용하면 의존성이 동일하지 않은 경우에만 컴포넌트를 다시 렌더링한다.. )
  • 전달한 값을 나중에 일부 Hook의 종속성으로 이용할 경우. 예를 들어, 다른 useMemo의 계산 값이 여기에 종속되어 있을 수 있다. 또 useEffect의 값에 종속되어 있을 수 있다.

 

✅참고 

https://react.dev/reference/react/useMemo  ( react - useMemo )

https://ko.react.dev/reference/react/useMemo ( react - useMemo 번역버전 ) 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is ( Object.is() ) 

'⭐FE' 카테고리의 다른 글

React useState 호출 시 무조건 렌더링 된다?  (0) 2023.11.19
zustand useshallow는 언제쓸까?  (2) 2023.11.19
storybook 파악하기  (0) 2023.09.17
[Typescript] Typescript 환경을 구성해보자  (0) 2022.07.10
[Javascript] es6 import, export 예시  (0) 2022.07.10
'⭐FE' 카테고리의 다른 글
  • React useState 호출 시 무조건 렌더링 된다?
  • zustand useshallow는 언제쓸까?
  • storybook 파악하기
  • [Typescript] Typescript 환경을 구성해보자
devWarrior
devWarrior
  • devWarrior
    devWarrior
    devWarrior
  • 전체
    오늘
    어제
    • 🧩Dev (263)
      • ⭐FE (34)
      • 🔒Algorithm (155)
      • ➕Etc. (11)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프론트엔드
    자스
    Algorithm
    그리디
    실버3
    실버4
    leetcode
    Lv2
    FE
    구현
    Easy
    실버1
    javascript
    프로그래머스
    nodejs
    js
    자바스크립트
    node.js
    react
    알고리즘
    DFS
    dp
    티스토리챌린지
    실버2
    BFS
    코테
    오블완
    골드5
    코딩테스트
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
devWarrior
useMemo 이해하기
상단으로

티스토리툴바