Web/React

React UseMemo, UseCallback, UseRef

괘창 2024. 6. 27. 11:36

■ UseMemo, UseCallback, UseRef

- useMemo()

:  Memoized value를 리턴하는 hook

Memoization
최적화를 위해 사용하는 개념
비용이 높은, 즉 연산량이 많이 드는 함수의 호출 결과를 저장해 두었다가 같은 입력 값으로
함수를 호출하면 새로 함수를 호출하는 것이 아닌 저장해 놓은 호출 결과를 반환하는 것
Memoization된 결과 값을 영어로 Memoized Value라 한다.

 


- useMemo() 사용법

# useMemoHook은 파라미터로 memoizedValue를 생성하는 create 함수와 의존성 배열을 받는다.

# Memoization 개념처럼 의존성 배열에 들어가 있는 변수가 변했을 때 새로 create 함수를 노출하여

   결과값을 반환하며, 아닌 경우에는 기존 함수의 결과값을 그대로 반환한다.

# useMemo 훅을 사용하면 컴포넌트가 다시 랜더링될 때마다 높은 연산량의 작업이 반복되는 것을 피할 수 있다.

useMemo로 전달된 함수는 랜더링이 일어나는 동안 실행된다.

랜더링이 일어나는 동안 실행되서는 안될 작업을 useMemo의 함수에 넣으면 안된다.

ㄴ 예 : useEffectHook에서 실행되어야할 사이드 이펙트

 ㄴ 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 작업 등은 랜더링이 일어나는 동안

      실행되서는 안되기 때문에 useMemo 훅 함수에 넣으면 안되고 useEffectHook을 사용해야 한다.

 

# useMemo 훅에 의존성 배열을 넣지 않으면 의미가 없다!

 

# 의존성 배열에 빈 배열을 넣게 되면 컴포넌트가 마운트 될 때만 create 함수가 호출되며,

   마운트 이후에는 값이 변하지 않는다.

※ 마운트 시점에만 한 번 값을 계산할 필요가 있는 경우에만 위 코드와 같이 의존성에 빈 배열 사용

# 대부분 useMemo 훅에 의존성 배열의 변수들을 넣고 해당 변수들의 바뀜에 따라 새로운 값을 계산할 때 사용


- useCallback()

: useMemo() Hook과 유사하지만 값이 아닌 함수를 반환한다.

  컴포넌트가 랜더링 될 때마다 매번 함수를 새로 정의하는 것이 아닌

  의존성 배열의 값이 바뀐 경우에만 함수를 새로 정의해서 리턴해주는 것이 특징

 

 

- useCallback() 사용법

# useCallbackHook은 유즈메모훅과 동일하게 함수와 의존성 배열을 파라미터로 받는다.

  파라미터로 받는 이 함수를 callback이라 한다.

# 의존성 배열에 있는 변수 중 하나라도 변경도면 메모이제이션된 콜백 함수를 반환한다.

 

# 유즈 콜백 훅을 사용하지 않고 컴포넌트 내에 함수를 정의할 시 매번 랜더링 발생 시 함수가 새로 정의된다.

# useCallbackHook을 사용하여 특정 변수의 값이 변한 경우에만 함수를 다시 정의하여 불필요한 반복작업을 없애준다.

 

 

예시 코드)

 

# useCallback을 사용하면 특정 변수의 값이 변한 경우에만 함수를 다시 정의하게 되므로
   함수가 재저의 되지 않은 경우에는 자식 컴포넌트도 재 랜더링이 일어나지 않는다.

# 의존성 배열에 빈 배열이 들어갔기 때문에 컴포넌트가 처음 마운트되는 시점에만 함수가 정의되고
   이후에는 재정의 되지 않으며, 결국 자식 컴포넌트도 불필요한 재랜덩이 발생하지 않는다.


- useRef()

: Reference를 사용하기 위한 Hook

  React에서 레퍼런스란 특정 컴포넌트에 접근할 수 있는 객체를 의미한다.

  그리고 useRefHook은 이 레퍼런스 객체를 반환한다.

 

# current 속서은 현재 레퍼런스하고 있는 엘리먼트를 의미한다.

 

 

- useRef() 사용법

# 파라미터로 초기값을 넣으면 해당 초기값으로 초기화된 레퍼런스 객체 반환

# 초기값이 null 인 경우 current의 값이 null인 레퍼런스 객체 반환

# 반환된 레퍼런스 객체는 컴포넌트 라이프타임 전체에 걸쳐 유지된다.

※ useRefHook은 변경 가능한 current라는 속성을 가진 하나의 상자

 

 

예시 코드)

# useRefHook을 사용하여 버튼 클릭 시 input에 포커스를 하도록 하는 코드

# 초기 값은 null로 결과로 반환된 inputElim이란 레퍼런스 객체를 input 태그에 작성

   버튼 클릭 시 호출되는 함수에서 inputElim.current를 통해 실제 엘리먼트에 접근하여 포커스 함수 호출

 

 

# 리액트에서는 화면과 같이 코드를 작성하면 노드가 변경될 때마다 myref의 current 속성에

   현재 해당되는 DOM 노드를 저장한다.

# ref 속성과 기능은 비슷하나 useRefHook은 클래스의 instance 필드를 사용하는 것과

  유사하게 다양한 변수를 저장할 수 있다는 장점이 있다.

※ useRefHook은 일반적인 자바스크립트 객체를 리턴한다.

 

# 코로 current 속성을 변경한다고 해서 재 랜더링이 일어나지 않는다.


 

- DOM 노드에 연결되거나 분리되었을 경우에 다른 코드를 실행하고 싶다면?

# DOM 노드의 변화를 알기 위한 기초적인 방법

 

 

예제 코드)

# useCallbackHook을 사용하는 callbackRef를 사용하는 방식

# useRefHook을 사용하면 레퍼런스 객체가 current 속성의 변경 유무를 알려주지 않기 때문!

# callback-ref 방식을 사용하면 자식 컴포넌트가 변경되었을 때 알림을 받을 수 있고 이를 통해 다른 정보 업데이트 가능