React에서 컴포넌트의 상태 관리와 DOM 조작은 매우 중요합니다. 일반적으로 useState를 통해 상태를 관리하지만, 컴포넌트의 리렌더링과 관계없이 값을 유지하고 싶거나, 특정 DOM 요소에 직접 접근하고 싶을 때는 useRef를 사용하게 됩니다.
목차
위의 목차를 클릭하면 해당 글로 자동 이동 합니다.
1. useRef란?
useRef는 React에서 제공하는 Hook 중 하나로, 다음과 같은 기능을 제공합니다.
- 값 저장: 컴포넌트의 라이프사이클 동안 유지되며, 값이 변경되더라도 리렌더링을 발생시키지 않습니다.
- DOM 요소 접근: 특정 DOM 요소에 직접 접근하여, 이를 조작할 수 있습니다.
import React, { useRef } from 'react';
function App() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text"/>
<button onClick={handleFocus}>클릭</button>
</div>
);
}
위 코드에서는 useRef를 사용해 <input> 요소에 접근하고, 버튼을 클릭하면 입력 필드에 자동으로 포커스가 맞춰집니다. 이처럼 useRef는 직접적으로 DOM을 제어할 수 있는 강력한 도구입니다.
2. useRef vs useState: 언제 사용할까?
useRef는 useState와 비교될 때 그 차이가 명확해집니다. 둘 다 상태를 저장하는 역할을 하지만, 목적과 동작 방식이 다릅니다.
특징 | useRef | useState |
리렌더링 | 값이 바뀌어도 리렌더링을 발생시키지 않음 | 값이 바뀌면 컴포넌트를 리렌더링함 |
상태 유지 | 컴포넌트가 리렌더링되어도 값이 유지됨 | 컴포넌트가 리렌더링될 때 최신 상태를 반영 |
주요 사용 사례 | DOM 조작, 리렌더링 없이 값을 저장해야 할 때 | UI에 영향을 주는 상태를 관리할 때 |
useRef는 주로 리렌더링이 필요 없는 값, 즉 단순히 값을 저장하거나 DOM 요소에 접근할 때 사용됩니다. 반면 useState는 UI 갱신을 위해 상태 변경 시 리렌더링이 필요한 경우에 사용됩니다.
3. useRef의 사용 사례
3.1. DOM 요소 직접 조작
가장 흔한 사용 사례는 특정 DOM 요소에 접근하는 것입니다. 예를 들어, 사용자 입력 필드에 자동으로 포커스를 맞추거나, 스크롤 위치를 제어하는 경우에 유용합니다.
import React, { useRef, useEffect } from 'react';
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
이 코드에서는 컴포넌트가 처음 마운트될 때 입력 필드에 자동으로 포커스가 맞춰집니다. useRef 덕분에 DOM에 직접 접근해 focus 메서드를 호출할 수 있습니다.
3.2. 이전 값 추적
컴포넌트가 리렌더링 될 때 이전 상태를 추적해야 하는 경우 useRef를 사용할 수 있습니다. 이는 상태 변경 전과 후의 값을 비교하는 데 유용합니다.
import React, { useState, useEffect, useRef } from 'react';
function PreviousValueComponent() {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count; // 현재 값을 이전 값으로 저장
}, [count]);
return (
<div>
<p>Current Count: {count}</p>
<p>Previous Count: {prevCountRef.current}</p>
<button onClick={() => setCount(count + 1)}>Count 증가</button>
</div>
);
}
여기서 prevCountRef는 count의 이전 값을 저장합니다. useState와 달리 useRef는 리렌더링을 발생시키지 않고 값을 유지하므로, 이전 값 추적에 적합합니다.
3.3. 타이머 및 외부 API와 함께 사용
비동기 작업을 처리하는 타이머나 외부 API 호출에서도 useRef는 유용합니다. 예를 들어, 컴포넌트가 원마운트될 때 타이머를 정리하거나, 외부 작업의 취소 여부를 체크하는 용도로 사용할 수 있습니다.
import React, { useState, useRef, useEffect } from 'react';
function TimerComponent() {
const [seconds, setSeconds] = useState(0);
const timerRef = useRef(null);
useEffect(() => {
timerRef.current = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => {
clearInterval(timerRef.current); // 타이머 정리
};
}, []);
return <p>Seconds: {seconds}</p>;
}
여기서는 useRef로 타이머 ID를 저장하고, 컴포넌트가 언마운트될 때 clearInterval을 통해 타이머를 정리합니다.
4. useRef 사용 시 주의할 점
- 리렌더링에 영향 없음: useRef로 관리하는 값이 변경되어도 컴포넌트는 리렌더링되지 않습니다. 이 점을 고려하여, UI 상태가 아닌 값들을 관리할 때만 사용해야 합니다.
- DOM 조작은 신중하게: useRef를 통한 직접적인 DOM 조작은 React의 선언적 방식과 반대되는 패턴이므로 꼭 필요한 경우에만 사용해야 합니다.
React의 useRef는 상태 관리와 DOM 조작을 더욱 세밀하게 할 수 있는 도구입니다. DOM 요소에 접근하거나 리렌더링 없이 값을 저장하고 싶을 때, 또는 타이머와 같은 비동기 작업을 처리할 때 매우 유용합니다. useState와의 차이점을 이해하고 적절한 상황에서 사용한다면, 더욱 깔끔하고 효율적인 코드를 작성할 수 있을 것입니다.
추천글
'개발 공부 일지 > React' 카테고리의 다른 글
[React] 리액트 생명 주기(Life Cycle) (3) | 2024.10.18 |
---|---|
[React] 리액트 useReducer (0) | 2024.10.16 |
[React] 리액트 Key - 리스트 렌더링 (0) | 2024.10.12 |
[React] 리액트 Router - 파라미터 & 쿼리 (0) | 2024.10.10 |
[React] 리액트 Router란? (1) | 2024.10.09 |