✅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 |