Develop+

useEffect, useState만 사용하지말고 useMemo, useCallback 사용해보자 본문

React

useEffect, useState만 사용하지말고 useMemo, useCallback 사용해보자

Sunny Buddy 2023. 1. 11. 01:10
728x90

리액트를 훅을 사용하다보면 useEffect와 useState만으로도 충분히 프로그램을 짤 수 있다.

그래서 useMemo, useCallback이라는 개념을 듣고 제대로 적용해 본 적이 없는 거 같다. 

이렇게 작동하는 코드로 만족하는 것이 새로운 것을 배우려는 마음까지도 좁게 만드는 거 같아 useMomo와 useCallbak 에대해 공부해보고자 한다.

 

일단 useMemo, useCallback을 배우기 전에 알고가야 할 두 가지는, 

함수형 컴포넌트도 "함수"라는 것이다. 함수가 실행될 때 내부에 있는 선언, 함수들이 매번 다시 선언이된다는 점이다. 

그리고 컴포넌트는 state와 props가 변경될 때 마다 리랜더링 된다는 점이다. 

그렇다면 리랜더링 될 때마다 내부의 변수선언, 함수들이 매번 다시 선언이 되는 것이고 메모리 자원이 소모가 된다.

 

첫번째로 useMemo에 대해 알아보자.

핵심은 memorization 된 값을 반환한다는 것이다. 

어떤 경우에 useMemo를 사용할 수 있을까? 예시를 들어보겠다.

a와 b 두개의 props를 받는 A라는 컴포넌트가 있다. A는 a와 b값을 받아 각각 데이터를 가공하는 함수를 사용해 가공된 값을 사용한다. 그런데 a와 b 둘다 새로운 값이 들어온 게 아니고 a 의 값만이 새로운 값이 들어왔는데도 A는 props가 변경되었기 때문에 리랜더링을 하게 되고 b의 데이터를 가공하는 함수도 또 계산을 해야한다. b는 변경되지 않았기 때문에 이전의 계산된 값을 써도 되도 되는데 참 아쉬운 상황이다. 우리는 이럴 때 useMemo 훅을 사용할 수 있다!

간단한 더하기, 빼기의 경우 useMemo이 눈의 띄는 효과를 내지 못하지만, 아주 복잡한 계산로직이 있는 경우에 사용하면 아주 적합하게 사용할 수 있다. react 공식 문서에서도 useMemo의 예시 함수로 computeExpensive를 사용한 것을 볼 수 있다. 

 

두번째로 useCallback는 언제 사용 할 수 있을까?

useCallback의 핵심도 마찬가지로 memorization된 함수를 반환한다는 것이다.

배우기 전 알아두어야 할 두가지 중에는 함수가 리랜더링 될 때마다 함수들도 매번 다시 선언이 되는 것을 말했다. 

이벤트 핸들러 함수나 API를 요청하는 함수를 주로 useCallback으로 선언하는 코드들이 많다. 

하지만 비싼 계산이 아니라면  useMemo를 권장하지 않는 것처럼 useCallback을 사용하는 것도 비용적으로 크게 차이나지 않는다. 리액트 문서에서는 하위컴포넌트에서 useMemo등으로 최적화가 되어있을때 props로 함수를 전달받을 때 사용성이 좋다고 나와있다. 하위컴포넌트에서 함수를 props로 받는 경우를 생각해보자. 

 

js에서는 원시타입인 문자열 'HELLO' 와  'HELLO' 두개가 같은 값인지 비교하면 true를 반환한다.
이는 다른 원시타입에서도 동일하다. 하지만 모든 원시타입(string, number, boolean)을 제외한 모든 것들(function, array, object, class...etc)은 자바스크립트 내에서 object 타입이기 때문에 같은 값을 가지는 object 을 비교해도 false를 뱉느다.
부모컴포넌트의 state값을 변경하는 setSomething 함수를 props로 넘긴다면, 컴포넌트는 props로 동일하지 않은 값을 넘겨받는다고 인식하게된다.

 

이럴때 memorization이 된 함수인 useCallback 함수를 props에 넣어주면 새로운 함수를 받았다고 인식하지 않고, 동일한 함수를 props로 받았다고 인식하게되기 때문에, 이러한 이슈로 생기는 리랜더링을 방지할 수 있다.

 

이렇게 나에게는 익숙하지 않았던 useMemo와 useCallback에 대해 공부해보았다. 

업무에서 useMemo와 useCallback을 적용할 곳이 있는지 찾아보고 불필요한 리랜더링을 줄여보고자 한다!

적용 후 후기를 가지고 돌아와보겠다 :)

728x90