본문 바로가기
프로그래밍

useMemo 대 useCallback React: 유사점과 차이점

by it-view 2022. 3. 10.
반응형

두 리액트 후크의 비교

리액트 개발의 세계에서 우리가 받은 가장 위대한 것 중 하나는 후크입니다. 2019년에 리액트 훅의 도입은 논리를 다루는 완전히 새로운 방법을 가능하게 했다. Hooks는 여러 구성 요소에서 로직을 구현, 구조화, 격리 및 공유할 수 있는 방법을 크게 개선했습니다.

3년이 지난 지금도 이 글을 쓰는 순간, 저는 특정 훅이나 그 내면에 대한 새로운 것들을 발견하고 배우고 있습니다. 최근 저의 호기심을 자극한 것 중 하나는 useMemo와 useCallback이라는 두 가지 리액트 훅이었습니다.

그들의 목적

 

두 훅의 목적은 메모화를 통한 리액트 성능 향상입니다. 간단히 말해서, 메모화는 입력을 기반으로 계산된 값을 저장하는 캐싱 기법이다. 함수를 동일한 입력으로 호출하면 계산을 건너뛰고 캐시된 값을 반환합니다. 입력이 변경되면 값을 다시 계산하여 캐시합니다.

useMemo와 useCallback 둘 다 리액트 개발자들이 특정 엔티티를 쉽게 메모할 수 있게 해주며, 이는 잠재적으로 컴포넌트 재렌더를 방지하는 데 사용될 수 있다. useCallback hook은 이름에서 알 수 있듯이 콜백을 메모하기 위한 것입니다. useMemo hook은 원시 요소 및 객체와 같은 다른 모든 정적 엔티티에 사용할 수 있습니다.

유사성

실제로 useMemo와 useCallback hook은 동일한 목적을 공유할 뿐만 아니라 용도가 매우 유사하다. 두 후크 모두:

  • 해당 문제에 대한 모든 후크와 마찬가지로 구성 요소의 최상위 수준에서 호출되어야 합니다.
  • 첫 번째 인수로 함수를 받아들이고 두 번째 인수로 종속성 배열을 받아들입니다.
  • 제공된 함수에 따라 렌더 전체에서 참조적으로 안정적인 메모된 값을 반환합니다.
  • 종속성 배열에서 변경 사항이 감지되면 함수에 따라 값을 다시 계산하고 메모합니다.
 

차이점이 있나요?

그렇다면 흥미로운 질문은 useMemo와 useCallback 사이에 차이점이 있는가 하는 것입니다. 만약 그렇다면, 그것들은 정확히 무엇입니까?

이 글의 앞부분에서 이미 확립된 바와 같이 useCallback은 콜백을 메모하는 데만 사용될 수 있으며 useMemo는 기본적으로 다른 모든 자바스크립트 엔티티를 위한 것이라는 작은 차이점이 있다. 이들의 목적과 용도는 기본적으로 동일하기 때문에 서로 다른 주체가 후크의 유일한 차이점인 것처럼 느껴집니다.

그러나 개념적으로는 useMemo를 사용하여 useCallback을 통해 함수를 메모하는 동작을 흉내내는 것이 가능하다. 이상하게 보이겠지만, Memo를 사용하고 공장 기능에서 기능을 반환할 수 있습니다. 이론적으로는 useCallback을 사용하는 것과 같습니다.

만약 그것이 유지된다면, 그것은 편리함을 제외하고 useCallback과 useMemo 사이에 실질적인 차이가 없다는 것을 의미하기도 한다. 따라서 문제는 useCallback hook을 통해 함수를 메모하는 것과 useCallback() => doSomething()을 수행하는 것, useMemo를 통해 함수를 메모하는 것과 useMemo(() => => doSomething())를 통해 콜백을 반환하는 것 사이에 차이가 있는지 여부입니다.

 

깊숙이 파고들기

공식 Response hook 문서에는 useCallback(fn, depos)이 useMemo(() => fn, depos)와 동등하다는 것을 알리는 작은 노트가 이미 있다. 그러나 이것은 우리에게 많은 정보나 맥락을 제공하지 않습니다. 예를 들어, 이것이 모든 유형의 함수, 특히 인라인 함수에도 적용됩니까? 엣지 케이스가 있나요? 이를 위해 두 훅의 구현에 대해 살펴보겠습니다.

두 후크의 코드는 리액트-조정기 패키지, 특히 후크에 대한 새로운 리액트 파이버 구현이 있는 파일에 있습니다. 거기서 모든 후크에 대한 코드를 찾을 수 있습니다. 언제 마운트되는지, 언제 업데이트해야 하는지. 우리가 고려하고 있는 두 개의 메모화 후크 사이의 차이점을 발견하기 위해서는 updateCallback과 updateMemo의 업데이트 기능을 살펴봐야 한다.

useCallback hook의 업데이트 기능부터 시작하겠습니다.

여기에는 몇 가지 사항이 있지만 가장 중요한 것은 useCallback hook에 대한 후속 호출이 다음과 같은 방식으로 처리된다는 것입니다.

 
  • 이 후크를 호출하는 데 사용된 이전 종속성(상태)이 검색되고 현재 종속성과 비교됩니다.
  • 동일할 경우 후크는 이전 실행에서 캐시된 콜백을 반환합니다.
  • 만약 그것들이 동일하지 않다면 함수는 hook.memoizedState 내부의 현재 종속성과 함께 현재 콜백을 캐시할 것이다. 그런 다음 후속 통화에서 잠재적으로 재사용될 수 있습니다.

이제 useMemo의 업데이트 기능 구현에 대해 살펴보겠습니다.

두 업데이트 기능을 비교해보면 거의 동일함을 알 수 있습니다. 두 훅은 이후 훅 호출 시 기본적으로 동일한 절차를 거칩니다. 우리가 발견할 수 있는 유일한 차이점은 메모되는 가치입니다.

useCallback의 경우, 메모되고 있는 값은 직접적으로 첫 번째 함수 인수입니다. useMemo의 경우, 첫 번째 함수 인수도 사용되지만 약간 다른 방식으로 사용된다. 또한 콜백과 비교하여 nextCreate라는 다른 이름을 가진 것을 알 수 있습니다. 제공된 함수를 즉시 메모하는 대신 후크는 함수를 호출하여 결과 값을 메모합니다.

이를 바탕으로 useCallback() => doSomething()과 useMemo() => () doSomething()의 차이가 있는지에 대한 원래 질문을 다시 살펴볼 수 있습니다. 후자에 초점을 맞춘다면, 후크가 공장 함수를 호출하고 마운트에서 () => doSomething() 함수를 캐시한다는 것을 의미한다. 종속성이 변경되지 않는 한 캐시된 버전을 계속 사용합니다.

 

이것은 useCallback도 하는 일이지만, 공장 함수를 호출하고 정의된 함수를 대신 사용하지 않는다. 이전의 호출과 비교만 되는 React hooks에서 메모화가 구현되기 때문에, 이는 인라인 정의된 함수들 또한 두 후크 사이에서 완벽하게 잘 동작하고 정확하게 동일하다는 것을 의미한다.

결론

이 글에서는 메모화를 위해 일반적으로 사용되는 useCallback과 useMemo를 비교했습니다. 둘 다 성능 리액트 개발의 토대에 서 있습니다. 언뜻 보면 차이가 있는지 의심이 들 정도로 두 훅은 매우 유사하다. 실제적인 차이가 있나요, 아니면 편의상 같은 논리에 다른 이름을 가진 포장지인가요?

이 질문에 답하기 위해, 이 기사는 두 훅의 구현에 대해 깊이 파고들었다. 그곳에서 우리는 메모화된 값이 결정되는 방법을 제외하고 두 훅 뒤의 논리가 기본적으로 같다는 것을 발견했다. 구현 방식과 리액트 후크에서의 메모화가 구현되는 방식을 고려할 때 useCallback을 사용하여 (인라인) 함수를 정상적으로 메모하거나 useMemo에서 반환하는 것과 차이가 없다.

이를 바탕으로 두 훅 사이에 기술적인 차이가 없고 편의상 두 개의 별도 훅이 존재한다고 결론 내릴 수 있다.

 

댓글