useRef의 첫 번째 얼굴: DOM 금고

662025년 10월 20일3

리액트의 세계는 선언적인 프로그래밍을 지향했다. 개발자는 “무엇을 보여줄지”를 코드로 선언하고, “어떻게 화면을 그릴지”는 리액트에게 맡겼다. DOM(Document Object Model)을 직접 조작하는 것은 일반적으로 금기시되었다.

하지만 때로는 이 금기를 깨야만 하는 순간이 찾아왔다.

“페이지가 로드되면, 검색창에 자동으로 포커스를 주고 싶습니다.”
“특정 요소의 크기나 스크롤 위치를 직접 읽어와야 합니다.”
“외부 라이브러리(예: D3.js)를 연동해야 하는데, 그 라이브러리는 특정 DOM 노드를 직접 제어해야만 합니다.”

이러한 명령적인(imperative) 작업을 처리하기 위해, 클래스 컴포넌트에는 React.createRef()라는 기능이 있었다. ref 객체를 만들어 DOM 요소에 연결하면, this.myRef.current를 통해 해당 DOM 노드에 직접 접근할 수 있었다.

함수형 컴포넌트의 시대가 열리면서, 이 ref를 생성할 새로운 방법이 필요했다.
리액트 팀은 useRef라는 이름의 새로운 훅을 도입했다.

댄은 이 훅의 가장 기본적인 사용법을 시연했다.
그의 목표는, 컴포넌트가 렌더링되자마자 <input> 요소에 자동으로 포커스를 주는 것이었다.

import React, { useRef, useEffect } from 'react';

function SearchInput() {
  // 1. useRef를 호출하여 ref 객체를 생성한다.
  const inputRef = useRef(null);

  useEffect(() => {
    // 2. useEffect를 사용하여, 렌더링이 끝난 후에
    //    ref의 current 프로퍼티에 접근하여 focus() 메서드를 호출한다.
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }, []); // 마운트 시 한 번만 실행한다.

  // 3. ref 속성을 통해 JSX 요소와 ref 객체를 연결한다.
  return <input ref={inputRef} type="text" />;
}

useRef의 동작은 useState와는 사뭇 달랐다.
useRef(initialValue)를 호출하면, 리액트는 { current: initialValue }라는 형태의 평범한 자바스크립트 객체를 반환했다.
이 객체는 아주 특별한 성질을 가지고 있었다. 리액트는 이 객체를 컴포넌트의 전체 생애주기 동안 계속해서 유지했다. 리렌더링이 일어나도, useRef는 항상 이전에 만들었던 바로 그 객체를 그대로 반환했다.

개발자는 이 ref 객체를 ref라는 특수한 prop을 통해 DOM 요소에 연결할 수 있었다.
연결이 완료되면, 리액트는 ref 객체의 current 프로퍼티에 해당 DOM 노드를 자동으로 할당해 주었다.

이제 개발자는 inputRef.current를 통해, 언제든지 <input> DOM 노드에 직접 접근하여 focus(), blur() 같은 명령적인 API를 호출하거나, clientWidth 같은 프로퍼티를 읽을 수 있게 되었다.

useRef는 선언적인 리액트의 세계와 명령적인 DOM의 세계를 잇는, 안전한 다리 역할을 했다.
그것은 마치 특정 DOM 요소를 보관하는, 안전한 ‘금고’와도 같았다. useRef를 통해 금고를 만들고(useRef 호출), 금고에 라벨을 붙여 요소에 연결하면(ref prop), 리액트가 그 금고 안에 실제 DOM 요소를 넣어주는 셈이었다.

여기까지가 useRef의 첫 번째 얼굴이었다.
클래스 시절의 createRef를 대체하는, 비교적 단순하고 이해하기 쉬운 역할.

하지만 댄과 리액트 팀은 useRef에 훨씬 더 중요하고도 교묘한 두 번째 얼굴이 숨겨져 있음을 알고 있었다.
그것은 useRef가 가진 아주 특별한 성질, 즉 current 프로퍼티를 변경해도 리렌더링이 일어나지 않는다는 사실에서 비롯된 것이었다. 이 두 번째 얼굴은 useRef를 단순한 DOM 접근 도구를 넘어, 훅 패러다임에서 독특한 역할을 수행하는 비밀 병기로 만들어줄 터였다.