react로 커스텀 오디오 플레이어를 작업하고 있는데, useRef라는 hook을 처음 알게 되어 정리해보려 한다.
useRef는 DOM 요소에 직접 접근할 때 사용한다. 바닐라JS에서 document.querySelector와 같은 역할을 한다고 할 수 있다.
const ref = useRef(initialValue);
initialValue를 설정해주면 current 프로퍼티 안에 initialValue가 들어간다. useRef는 객체를 반환하며, 콘솔창에 찍어보면 다음과 같이 출력된다.
const cntRef = useRef(0);
console.log(cntRef); // {current: 0}
useRef의 또 다른 특징은 useState와 비교해보면 더 이해가 쉽다. 가장 큰 차이점은 리렌더링에 있다고 할 수 있겠다. useState는 state가 변경이 될 때마다 리렌더링이 되는 반면, useRef는 리렌더링이 발생하지 않는다. 따라서, 값이 변경될 때마다 화면에 렌더링 되어야한다면 useState를, 그렇지 않다면 useRef를 사용하면 된다.
| useState | useRef |
|---|---|
| - 상태(state)를 관리하기 위해 사용되는 hook이다. - 함수형 컴포넌트에서 상태를 관리할 수 있게 해준다. - state가 변경될 때마다 컴포넌트가 리렌더링된다. | - DOM요소나 다른 값에 대한 참조를 생성하고 관리할 때 사용된다. - 컴포넌트 리렌더링과 관계 없이 값이 유지된다. - 값이 변경되어도 컴포넌트가 리렌더링 되지 않는다. |

위의 예제에서 볼 수 있듯이 useState는 변경이 될 때마다 리렌더링 되면서 화면에 바로 반영이 되지만, useRef는 값은 변하지만 리렌더링이 되지 않아 화면에 반영이 되지 않는다. 다시 state++ 버튼을 클릭해서 리렌더링이 일어나자 변경되었던 useRef 값이 화면에 반영되는 것을 볼 수 있다.
import { useRef } from "react";
function Player(){
const audioEl = useRef(null);
useEffect(() => {
audioEl.current.play();
}, []);
return(
<audio src={파일 경로} ref={audioEl}></audio>
)
}
위와 같이 useRef를 사용하면 <audio>, <video> 요소에 직접 접근할 수 있고 play(), pause() 메서드 등 미디어를 제어할 수 있는 web API를 활용하여 브라우저에서 미디어를 재생할 수 있다.
또한, 미디어 재생 시간과 같은 데이터는 리렌더링과는 상관없이 계속 업데이트를 해야하기 때문에, 상태와 관련없이 값을 저장하고 유지할 수 있는 useRef를 사용하는 것이 효과적이다.