리액트에서는 DOM 요소에 접근하기 위해 주로 ref를 쓴다. document.getElementsByClassName 등을 쓰는 게 아니라 ref를 쓰는 이유는 무엇일까?
React로 웹 애플리케이션을 개발하다보면, 간혹 React 컴포넌트가 아닌 HTML 엘리먼트에 직접 접근해서 DOM API를 이용해 제어할 필요가 있다. 이럴 때 React의 독특한 속성인 ref를 사용할 수 있다.
리액트는 실제 DOM이 아니라 가상 DOM을 사용하기 때문에 실제 DOM에 접근하는 document.getElementByClassName 등을 사용하면 에러가 발생한다. 따라서 직접 접근하지 않고 가상 DOM 자체에서 DOM 요소에 접근할 수 있는 ref를 사용한다.
Ref를 사용해야하는 상황
1) React에서 State으로만 해결할 수 없고, DOM을 반드시 직접 건드려야할 때
input에 focus 주기
Canvas 요소에 그림 그리기
직접적인 애니메이션 실행
서드 파티 DOM 라이브러리를 React와 같이 사용할 때
스크롤박스에서의 특정한 이벤트 처리 등
2) 컴포넌트를 렌더링 시키지 않고, DOM에만 접근해 원하는 효과를 주고자할 때
ref는 state와 다르게 값이 변경된다고 해서 컴포넌트를 리렌더링 시키지 않는다.
그래서 주로 focus나 text를 선택할때 많이 사용된다.
React의 ref 속성은 HTML element의 레퍼런스를 변수에 저장하기 위해서 사용한다.
예를 들어, 다음과 같이 input 엘리먼트에 ref 속성으로 inputRef라는 변수를 넘기게 되면, 우리는 이 inputRef 객체의 current 속성을 통해 input 엘리먼트에 접근할 수 있고, DOM API를 이용해 제어할 수 있게 된다.
<input ref={inputRef} />
ex1) input 엘리먼트 제어
import React, { useRef } from "react";
function Field() {
const inputRef = useRef(null);
function handleFocus() {
inputRef.current.disabled = false;
inputRef.current.focus();
}
// 입력란을 원래대로 비활성화 시켜주는 버튼도 어렵지 않게 추가로 구현할 수 있다.
function handleReset() {
inputRef.current.disabled = true;
inputRef.current.value = "";
}
return (
<>
<input disabled type="text" ref={inputRef} />
<button onClick={handleFocus}>활성화</button>
<button onClick={handleReset}>초기화</button>
</>
);
}
ex2) audio 엘리먼트 제어
import React, { useRef } from "react";
import music from "./music.mp3";
function Player() {
const audioRef = useRef(null);
const handlePlay = () => {
audioRef.current.play();
};
const handlePause = () => {
audioRef.current.pause();
};
return (
<>
<figure>
<figcaption>Eyes on You (Sting) - Network 415:</figcaption>
<audio src={music} ref={audioRef}>
Your browser does not support the
<code>audio</code> element.
</audio>
</figure>
<button onClick={handlePlay}>재생</button>
<button onClick={handlePause}>중지</button>
</>
);
}
참조:
Ref를 사용하는 이유
항해99 3주차 리액트 입문 전 알아야 할 기본 개념
Ref와 DOM
[React] ref로 HTML 엘리먼트에 접근/제어하기