React

react hook -useRef

Suna[Frontend Study] 2026. 1. 6. 14:39

 

useRef 

  • 컴포넌트가 다시 렌더링되더라도 기존 상태값을 유지하는 변수를 생성
  • useState는 값이 변경되면 컴포넌트가 다시 렌더링되지만 useRef는 값이 변경되어도 컴포넌트가 다시 렌더링되지 않음
  • 태그에 ref 속성을 추가하면 브라우저 DOM 엘리먼트에 직접 접근 가능
  • 포커스, 미디어 재생, 애니메이션 실행 등과 같은 작업은 useRef를 사용해 브라우저 DOM에 직접 접근하여 제어해야 함
const ref = useRef(initialValue);

매개변수

  • initialValue: 초기값

리턴값

  • current라는 상태값 또는 DOM 요소가 있는 속성 하나가 정의된 객체
 

 

1. useState vs useRef 의 비교 - 저장공간,변수관리 

State

  • state가 변경되면 컴포넌트는 리렌더링된다
  • 리렌더링이 발생하면
    👉 컴포넌트 함수가 다시 실행된다
  • 이때 컴포넌트 내부의 일반 변수들은 다시 초기화된다
  • 따라서 의도하지 않은 리렌더링이 발생하면 성능 문제가 생길 수 있다

Ref

  • ref의 값이 변경되어도 리렌더링은 발생하지 않는다
  • 컴포넌트가 다시 렌더링되지 않기 때문에
    👉 변수 값이 그대로 유지된다
  • ref는 렌더링과 무관하게 값을 보존해야 할 때 사용한다.

 
 

import { useRef, useState } from "react";

export const Ref = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(0);

  const handleUp = () => {
    setCount((pre) => pre + 1);
  };

  const handleRefUp = () => {
    countRef.current = countRef.current + 1;
  };
  console.log("렌더링");
  return (
    <div id="counter">
      <p>state {count}</p>
      <p>countRef {countRef.current}</p>
      <button onClick={handleUp} className="bg-red-300 mb-2">
        state증가
      </button>
      <br></br>
      <button onClick={handleRefUp} className="bg-red-300 active:bg-gr-600">
        Ref 증가
      </button>
    </div>
  );
};

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

위 영상에서는 state와 ref의 차이로 인해 화면 업데이트 방식이 달라지는 것을 확인할 수 있다.
먼저, state 값을 증가시킬 때마다 컴포넌트가 다시 렌더링되는 것을 확인할 수 있다.
이는 state가 변경되면 React가 해당 컴포넌트를 리렌더링하여 UI를 다시 그리기 때문이다.
반면, ref 값을 여러 번 증가시켜도 화면에는 즉시 반영되지 않는다.
 
왜 그럴까? 
 
이는 ref의 값이 내부적으로는 변경되고 있지만,
ref의 변경은 컴포넌트를 다시 렌더링시키지 않기 때문이다.
이후 state 버튼을 눌렀을 때, 컴포넌트가 다시 렌더링되면서
그동안 변경되어 있던 ref의 값이 한 번에 화면에 반영되는 것을 확인할 수 있다.
 
즉,

  • ref는 값이 변경되어도 렌더링을 발생시키지 않는다
  • 따라서 화면은 이전 렌더 시점의 값을 그대로 유지한다
  • 이후 state 변경으로 리렌더링이 발생하면
    → 그 시점에 ref에 저장된 최신 값이 화면에 반영된다

 
 
그렇다면 Ref의 장점은? 
 
만약 컴포넌트 내부에 매우 자주 변경되는 값을 state로 관리한다면,
그 값이 변경될 때마다 불필요한 렌더링이 계속 발생하게 된다.
이때 해당 값을 state가 아닌 ref로 관리하면,
값은 계속 변경되지만 렌더링은 발생하지 않기 때문에 성능상 이점을 얻을 수 있다.
 
 
 

2. useRef를 사용하여 DOM에 접근하기 

 

import { useEffect, useRef, useState } from "react";

export const Ref = () => {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  const login = () => {
    alert("ref DOM에 접근하기 성공");
  };
  return (
    <div id="counter">
      <input type="text" ref={inputRef} className="border border-active" />
      <button className="bg-red-300 active:bg-gr-600" onClick={login}>
        login
      </button>
    </div>
  );
};

 
 

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

 화면을 보면, 새로고침해도 input에 focus가 유지되는 것을 확인할 수 있다.
이는 ref를 사용하여 input DOM에 직접 접근했기 때문이다.