- Published On
React hooks - useRef
useRef
는 React의 훅(Hook) 중 하나로, 주로 DOM 엘리먼트에 직접 접근하거나
렌더링과 관련 없는 값을 저장
할 때 사용됩니다.
useState
와 달리, 값이 변경되어도 컴포넌트를 다시 렌더링하지 않는 특징
이 있습니다.
useRef의 정의와 기본 문법
useRef
는 값이 변경되더라도 컴포넌트를 다시 렌더링하지 않는 값
을 유지하거나, DOM 엘리먼트에 직접 접근
하는 데 사용됩니다.
import { useRef } from "react";
// 일반적으로 초기값으로 null을 사용합니다.
const ref = useRef(initialValue);
초기값으로 null을 사용하는 이유
- DOM 엘리먼트가 렌더링되기 전까지 null로 초기화하여 안전하게 접근.
- 초기 상태를 명시적으로 나타냄.
- null은 값이 비어 있음을 표현하는 일반적인 관례.
- React의 DOM 참조 방식과 일관성 유지.(표준 관례)
주요 예시
1. DOM 엘리먼트에 접근
React에서 DOM 엘리먼트에 직접 접근해야 할 때 useRef를 사용합니다.
버튼 클릭 시 ref.current가 어떻게 변하는지 콘솔 로그를 통해 확인해 보겠습니다.
import { useRef } from "react";
function FocusInput() {
const inputRef = useRef(null);
const handleFocus = () => {
console.log("Before focus:", inputRef.current); // 현재 DOM 요소를 출력
inputRef.current.focus();
console.log("After focus:", inputRef.current); // focus 메서드 호출 후 출력
};
return (
<div>
<input ref={inputRef} type="text" placeholder="포커스를 받아요!" />
<button onClick={handleFocus}>포커스</button>
</div>
);
}
-
버튼 클릭 전:
inputRef.current
는input 태그
의 엘리먼트를 가리킵니다. -
버튼 클릭 후: DOM 요소의
focus 상태가 변경
됩니다.(autofocus)
Before focus: <input type="text" placeholder="포커스를 받아요!">
After focus: <input type="text" placeholder="포커스를 받아요!" autofocus>
2. 렌더링과 관련 없는 값 관리
useRef는 값이 변경되더라도 렌더링을 트리거하지 않는 값을 관리할 때 유용합니다.
예를 들어, 폼 입력 중복 방지와 같은 실용적인 기능을 구현할 수 있습니다.
아래의 코드처럼 사용자가 동일한 값을 여러 번 제출하지 못하도록 막을 수 있습니다.
import { useRef, useState } from "react";
function PreventDuplicateSubmission() {
const [inputValue, setInputValue] = useState("");
const lastSubmittedValue = useRef(""); // 마지막 제출 값을 저장
const handleSubmit = () => {
if (inputValue === lastSubmittedValue.current) {
alert("중복된 값은 제출할 수 없습니다.");
return;
}
// 새로운 값 제출
lastSubmittedValue.current = inputValue;
console.log("제출된 값:", inputValue);
setInputValue(""); // 입력 필드 초기화
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="값을 입력하세요"
/>
<button onClick={handleSubmit}>제출</button>
<p>마지막 제출 값: {lastSubmittedValue.current}</p>
</div>
);
}
이 코드에서 초기값을 null이 아닌 ""
빈 문자열로 설정한 이유는
null인 경우 아래의 경우가 있을때, 코드가 길어질 수 있기 때문입니다.
if (inputValue === lastSubmittedValue.current) {
alert("중복된 값은 제출할 수 없습니다.");
}
if (
lastSubmittedValue.current === null ||
inputValue === lastSubmittedValue.current
) {
alert("중복된 값은 제출할 수 없습니다.");
}
- renderCount는 렌더링 횟수를 저장하지만, 값이 변경되어도 컴포넌트를 다시 렌더링하지 않습니다.
- useEffect를 통해 렌더링 횟수를 추적하고, 값을 증가시킵니다.
3. 값의 이전 상태 추적
useRef를 사용하여 컴포넌트의 이전 상태를 저장할 수 있습니다. 이는 값이 변경되었을 때 이전 값을 비교하거나 로그를 남기고 싶을 때 유용합니다.
import { useEffect, useRef, useState } from "react";
function PreviousValueTracker() {
const [count, setCount] = useState(0);
const prevCount = useRef(0);
useEffect(() => {
prevCount.current = count; // 이전 값을 저장
}, [count]);
return (
<div>
<p>현재 값: {count}</p>
<p>이전 값: {prevCount.current}</p>
<button onClick={() => setCount(count + 1)}>값 증가</button>
</div>
);
}
- prevCount는 count의 이전 상태를 저장하며, 렌더링과 관계없이 유지됩니다.
- useEffect는 count가 변경될 때마다 prevCount.current에 현재 값을 저장합니다.
useRef의 주요 특징
특징 | 설명 |
---|---|
렌더링 트리거 없음 | useRef 로 관리되는 값이 변경되어도 컴포넌트는 다시 렌더링되지 않습니다. 반면, useState 는 상태 변경 시 컴포넌트를 다시 렌더링합니다. |
DOM 엘리먼트 접근 | ref 속성을 DOM 요소에 전달하면 해당 DOM 요소를 가리킬 수 있습니다. 이를 통해 포커스, 스크롤 위치 등 DOM 조작이 가능합니다. |
값의 지속성 | 컴포넌트가 언마운트되지 않는 한, useRef 로 관리되는 값은 컴포넌트의 수명 동안 유지됩니다. |
useRef와 useState의 차이점
특징 | useRef | useState |
---|---|---|
초기값 설정 | useRef(initialValue) | useState(initialValue) |
렌더링 트리거 | 값을 변경해도 컴포넌트를 다시 렌더링하지 않음 | 값을 변경하면 컴포넌트를 다시 렌더링 |
주요 사용 사례 | DOM 엘리먼트 접근, 렌더링과 무관한 값 관리 | 상태 관리, 값 변경 시 UI 업데이트 |
비교 | 주로 렌더링과 관계없는 데이터 저장 | UI 업데이트를 위한 상태 관리 |
이전 포스트
Next.js의 렌더링 과정연관된 포스트 구경가기
1. React 란?2. Redux3. Virtual DOM(가상 DOM)이란?4. React hook 이란?5. Debounce와 Throttle의 차이점 및 활용법6. 클로저와 렉시컬 스코프7. React hooks - useEffect8. React hooks - useState9. React hooks - useRef
간략히