[리액트] useRef 사용법

iberis2·2023년 2월 23일
0

React 리액트

목록 보기
1/20

useRef

리액트에서 DOM 엘리먼트의 주소값을 활용해야 하는 예외적인 경우 useRef 로 DOM 노드, 엘리먼트, 그리고 React 컴포넌트 주소값을 참조할 수 있다.

useRef를 사용하는 예외적인 경우

  • focus
  • text selection
  • media playback
  • 애니메이션 적용
  • d3.js, greensock 등 DOM 기반 라이브러리 활용

useRef 를 남용하는 것은 부적절하고, React의 특징이자 장점인 선언형 프로그래밍 원칙과 배치되기 때문에, 조심해서 사용해야한다.

useRef 사용 문법

import {useRef} from "react";

const App = () => {
  const divRef = useRef(null) // 변수에 useRef를 담아

  return (
    <div className="App">
      <div ref={divRef}></div> // 원하는 HTML DOM element 에 속성으로 넣어준다.
    </div>
  );
}

export default App;

const 변수 = useRef(value) 를 사용하면 current 프로퍼티를 가지고 있는 {current: value} 객체를 반환한다.

위 코드에서 divRef 변수는 {current: <div></div>} 를 담고 있다.

useRef / useState / 일반 변수 차이

값을 useRef, useState, let(또는 const)을 사용해서 저장하는 것에는 각각 차이가 있다.

useState 와 useRef

useState를 사용해 저장한 값(=상태)는 setState로 값이(=상태가) 변할 때마다 렌더링이 일어난다.
반면에 useRef를 사용해 저장한 값은 ref.current 값에 변화가 생겨도 렌더링이 일어나지 않는다.

위 코드에서 `State up` 버튼을 누르면 값의 변화를 즉시 화면에서 확인할 수 있지만 
`Ref up` 버튼을 누르면 화면에는 아무런 변화가 없다.
하지만 콘솔창을 확인해보면 Ref 로 저장한 값도 값이 변한 것을 확인할 수 있다.

이때 `State up` 버튼을 눌러 화면 렌더링이 발생하면, 변화된 Ref 값을 화면에서 확인할 수 있다.

값이 변할 때마다 화면 렌더링은 굳이 필요하지는 않을 때 useRef를 사용하면 렌더링 최적화에 이를 수 있다.

useRef와 일반 변수

값을 일반 변수에 저장해도, 변수의 값이 변할 때마다 화면이 렌더링되지 않는다.
하지만 일반 변수에 저장하는 것과 useRef 사용의 가장 큰 차이는
변수에 저장한 값은 화면이 렌더링이 되면 초기화된다는 것이다.

위 코드에서 `Ref up`과 `Var up` 버튼을 누르면 둘 다 화면에서 값의 변화를 확인할 수 없다.
하지만 콘솔창을 올려 확인해보면 둘 다 값이 변한 것을 확인할 수 있다.

이 때 `State up` 버튼을 눌러 화면 렌더링이 발생하면, 
변화된 Ref 값은 화면에서 확인할 수 있지만, 
Var 값은 초기화 되어 0이 된다.

리액트는 함수형 컴포넌트로 렌더링이 일어날 때마다 함수를 새로 호출하기 때문에, 함수 안의 모든 변수들이 초기화 된다.

useRef의 또 다른 특징은 DOM 요소에 직접 접근할 수 있다는 것이다.

⚠️ 사용시 주의할 점 :
조건부 렌더링으로 컴포넌트가 사라지거나 하는 경우 값이 없을 수도 있으므로 if(inputRef.current) 로 값이 있는지 확인하고 사용하는 것이 권장된다.

사용 예제

input 요소를 누르지 않아도 커서가 input창에 포커스 되어 있어서 바로 입력하도록 만들기
inputRef.current.focus();

코드 설명
① 첫 화면 렌더링되었을 때 때 입력창에 커서가 focus 되도록 useEffect()에 inputRef.current.focus()를 사용했다.

② input창에 입력 후 로그인을 누르면 입력창의 값(value)이 알림창으로 뜨도록 버튼 클릭 함수 popupHandler() 에서 inputRef.current.value로 input 엘리먼트의 value를 가져와서 사용했다.

③ 마지막으로 알림창을 닫은 후에도 input 창에 커서가 포커스 되도록 popupHandler()에서 한번 더 inputRef.current.focus()를 사용햇다.


참고 자료 : React Hooks에 취한다 - useRef 완벽 정리 1# 변수 관리 | 리액트 훅스 시리즈
React Hooks에 취한다 - useRef 완벽 정리 2# DOM 요소 접근 | 리액트 훅스 시리즈
코드스테이츠 유어클래스

profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글