렌더링 없이도 값을 저장하거나, DOM 요소를 직접 참조하고 싶을 때 쓰는 리액트 훅!
const countRef = useRef(0);
countRef.current += 1;
useState는 바꾸면 리렌더링됨 ❌
useRef는 바꿔도 리렌더링 안 됨 ⭕
→ "UI에 영향 줄 필요 없는 값" 저장 시 딱임
const inputRef = useRef(null);
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>포커스!</button>
→ document.querySelector() 쓰는 거 대신 리액트 방식으로 DOM에 접근함
| 기능 | useState | useRef |
|---|---|---|
| 값 바꾸면 리렌더링? | ⭕ | ❌ |
| 값 저장 가능? | ⭕ | ⭕ |
| DOM 접근 가능? | ❌ | ⭕ |
⚡ 실무 예시: 리렌더 횟수 세기
❌ useState는 무한 루프 날 수 있음
const [renderCount, setRenderCount] = useState(1);
useEffect(() => {
setRenderCount(renderCount + 1); // 무한 렌더링 😱
});
✅ useRef는 렌더링 없이 값 증가 가능
const renderCount = useRef(1);
useEffect(() => {
renderCount.current += 1; // 리렌더 없음!
});
| 항목 | useState | useRef |
|---|---|---|
| 🔁 값이 바뀌면 리렌더링? | ✅ 예 | ❌ 아니요 |
| 🧠 값 기억(저장)? | ✅ 예 | ✅ 예 |
| 💥 렌더링마다 초기화됨? | ✅ 컴포넌트 다시 렌더링되면 함수 안 변수는 초기화됨 | ❌ ref는 리렌더링과 상관없이 유지됨 |
| 📦 구조 | 그냥 값: const [x, setX] = useState(초기값) | 객체: const x = useRef(초기값) → x.current에 값 있음 |
| 🛠 언제 사용? | 값 바꾸면 화면도 바뀌어야 할 때 | 값 바꿔도 화면은 그대로일 때 (렌더링 유발 X) |
| 🧩 DOM 접근 가능? | ❌ 못함 | ✅ ref를 통해 DOM에 접근 가능 |