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에 직접 접근했기 때문이다.
'React' 카테고리의 다른 글
| [React] lazy loading을 사용한 초기 렌더링 최적화 (0) | 2026.03.17 |
|---|---|
| Suspense 와 Error Boundary를 사용한 로딩과 에러 처리 (0) | 2026.01.08 |
| react hook -useState와 useEffect (객체 deps를 곁들인..) (0) | 2026.01.06 |