[React] useRef에 대하여

천천히조금씩·2025년 4월 6일

React ...에 대하여

목록 보기
4/6

🎯 들어가며

리액트 앱 프로젝트를 진행하면서 useRef를 사용한 여러 기능들을 구현하고 있다. 슬라이드 배너, 클릭 위치에 따라 다른 위치에 뜨는 팝업창 등 여러 곳에 사용하긴 했는데 사실 gpt가 도와주고 구글링이 도와줘서 사용할 수 있었던 것이지 내가 아는 것이 아니었다. 그냥 써야 돼서 쓰는 것과 제대로 알고 적재적소에 쓰는 것은 다르다.

따라서 오늘은 useRef란 무엇인지 어떨 때 사용해야 효율적인지에 대해 알아보도록 하겠다.


📌 useRef 기본 개념

useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환한다. 반환된 객체는 컴포넌트의 전 생명주기를 통해 유지된다.

🚩 기본 사용법

✍ 생성

const 변수명 = useRef(초기값);

➡️ 이러한 결과 값으로 {current: 초기값}을 지닌 객체가 반환된다. 다음 렌더링에서 useRef는 동일한 객체를 반환한다.

useRef에서 기억할 것은 이러한 current라는 키 값을 지닌 프로퍼티가 생성되고 값에 어떤 변경을 줄 때도 current를 이용해서 한다는 점이다.

ref.current 프로퍼티를 변경해도 React는 컴포넌트를 리렌더링하지 않는다.

✍ 반환 요소에 접근

<input ref={변수명}/>

💻 예시

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
  	  // {ref.current}
      Click me!
    </button>
  );
}
  • JSX에 {ref.current} 를 표시하면 클릭 시 번호가 업데이트 되지 않는다.
    ref.current를 설정해도 리렌더링을 촉발하지 않기 때문이다.
    렌더링에 사용하는 정보는 state여야 한다.

❗주의사항
1. ref.current는 state와 달리 변이할 수 있다. 그러나 렌더링에 사용되는 객체를 포함하는 경우 변이해서는 안된다.
2. 초기화를 제외하고는 렌더링 중에 ref.current를 쓰거나 읽으면 안된다. 이벤트 핸들러(함수)나 useEffect를 통해 하자!
3. ref를 변경해도 리렌더링이 되지 않기 때문에 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 적합하다.
4. 리렌더링이 되지 않기에 화면에 즉각적으로 반영되는 정보를 저장하는 데에는 적합하지 않다.


📌 ref로 DOM 조작하기

  • ref를 사용하여 DOM을 조작하는 것이 일반적이다.
  1. 초기값이 nullref 객체를 선언한다.
import { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);
  // ...
  1. ref 객체 속성으로 조작하려는 DOM 노드의 JSX에 전달한다.
  // ...
  return <input ref={inputRef} />;
  1. React가 DOM 노드를 생성하여 화면에 그린 후 React는 ref 객체current를 DOM 노드로 설정한다.
    이제 <input>에 접근하여 focus()와 같은 메서드를 호출할 수 있다.
  function handleClick() {
    inputRef.current.focus();
  }

노드가 화면에서 제거되면 React는 current를 다시 null로 설정한다.

💻 DOM 조작 예시

  1. 텍스트 input에 focus 주기
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
  • 버튼을 클릭하면 input에 초점이 맞춰진다.
  1. 이미지 스크롤하기
import { useRef } from 'react';

export default function CatFriends() {
  const listRef = useRef(null);

  function scrollToIndex(index) {
    const listNode = listRef.current;
    // 다음 코드는 특정 DOM 구조를 가정합니다:
    const imgNode = listNode.querySelectorAll('li > img')[index];
    imgNode.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToIndex(0)}>
          Neo
        </button>
        <button onClick={() => scrollToIndex(1)}>
          Millie
        </button>
        <button onClick={() => scrollToIndex(2)}>
          Bella
        </button>
      </nav>
      <div>
        <ul ref={listRef}>
          <li>
            <img
              src="https://placecats.com/neo/300/200"
              alt="Neo"
            />
          </li>
          <li>
            <img
              src="https://placecats.com/millie/200/200"
              alt="Millie"
            />
          </li>
          <li>
            <img
              src="https://placecats.com/bella/199/200"
              alt="Bella"
            />
          </li>
        </ul>
      </div>
    </>
  );
}
  • 버튼을 클릭하면 이미지가 스크롤된다.
  • 목록 DOM 노드에 대한 ref를 사용한 다음 DOM querySelectorAll API를 호출하여 스크롤하려는 이미지를 찾는다.

🚩 useRef로 DOM 조작 시 자주 쓰는 메서드

메서드용도언제 사용하는가
focus()포커스 설정폼 제출 시 특정 인풋에 자동 포커스 줄 때 (예: 로그인 첫 입력창)
blur()포커스 해제사용자가 입력 후 포커스를 제거하고 싶을 때
scrollIntoView()요소로 스크롤 이동특정 섹션으로 부드럽게 스크롤할 때 (ex: 메뉴 클릭 → 해당 섹션 이동)
scrollTo(x, y)절대 위치로 스크롤특정 좌표로 스크롤할 때 (ex: 최상단 이동 등)
scrollBy(x, y)상대 위치로 스크롤현재 위치 기준으로 스크롤할 때 (ex: 100px 아래로 이동)
classList.add()클래스 추가특정 스타일을 동적으로 추가할 때 (ex: 에러 표시 등)
classList.remove()클래스 제거특정 스타일을 제거하고 싶을 때 (ex: 에러 해제 등)
classList.toggle()클래스 토글클릭 시 스타일을 켜고 끄고 싶을 때 (ex: 아코디언 메뉴)
getAttribute()속성 값 가져오기요소의 특정 속성 값을 읽어야 할 때 (예: data-id)
setAttribute()속성 값 설정동적으로 속성을 바꿔야 할 때 (예: aria-expanded 조작)
removeAttribute()속성 제거속성이 더 이상 필요 없을 때 제거 (예: disabled 해제 등)
getBoundingClientRect()요소 위치/크기 계산뷰포트 내에서 위치 측정할 때 (예: 툴팁 위치 계산 등)
element.style.property = value인라인 스타일 변경동적으로 스타일을 적용할 때 (ex: display: 'none')

😄 마치며

오늘은 useRef 훅에 대해서 알아보았다. focus, scroll 등 DOM을 조작하거나 리렌더링 없이 값을 저장할 때 사용한다고 생각할 수 있다. 주로 input 창의 focus 또는 스크롤 조작에 많이 사용할 수 있을 것 같다. 앞으로도 자유자재로 잘 사용할 수 있도록 노력해봐야겠다.

profile
지금이라도 시작해보자..!

1개의 댓글

comment-user-thumbnail
2025년 10월 27일

꾸준한 모습 멋져요!

답글 달기