React의 ref ✨
React에서 ref는 DOM 요소나 컴포넌트를 직접적으로 참조할 수 있는 비밀 통로 같은 존재입니다.
평소에는 React가 DOM을 관리하지만, 때로는 React의 관리를 살짝 벗어나 직접 DOM에 접근해야 할 때가 있죠.
오늘은 ref의 개념, 사용법, 그리고 실무에서의 활용 방법까지 하나씩 파헤쳐 보겠습니다. 🕵️♀️
ref란 무엇인가요? 🤔
ref는 React에서 특정 DOM 요소나 컴포넌트를 직접 참조할 수 있는 방법입니다.
React는 단방향 데이터 흐름과 가상 DOM을 통해 UI를 관리하지만, 다음과 같은 경우에는 DOM에 직접 접근이 필요할 수 있어요.
- 특정 DOM 요소에 포커스 설정
- HTML 요소의 크기 및 위치 측정
- 비표준 DOM 속성에 직접 접근
- 애니메이션이나 외부 라이브러리와의 통합
ref는 이런 상황에서 브라우저의 DOM 요소를 직접 다룰 수 있게 해줍니다.
ref를 사용하는 방법 🌟
React에서는 useRef와 createRef를 사용해 ref를 생성할 수 있습니다.
함수형 컴포넌트에서는 useRef, 클래스형 컴포넌트에서는 createRef를 주로 사용해요.
1. 함수형 컴포넌트에서의 useRef
import React, { useRef } from "react";
function TextInputWithFocusButton() {
const inputRef = useRef(null); // ref 생성
const focusInput = () => {
inputRef.current.focus(); // DOM 요소에 직접 접근
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>포커스 이동</button>
</div>
);
}
export default TextInputWithFocusButton;
주요 포인트
- useRef로 ref를 생성하면 inputRef는 { current: null } 객체를 반환합니다.
- ref는 current 프로퍼티를 통해 해당 DOM 요소를 참조할 수 있습니다.
2. 클래스형 컴포넌트에서의 createRef
import React, { Component } from "react";
class TextInputWithFocusButton extends Component {
constructor(props) {
super(props);
this.inputRef = React.createRef(); // ref 생성
}
focusInput = () => {
this.inputRef.current.focus(); // DOM 요소에 직접 접근
};
render() {
return (
<div>
<input ref={this.inputRef} type="text" />
<button onClick={this.focusInput}>포커스 이동</button>
</div>
);
}
}
export default TextInputWithFocusButton;
주요 포인트
- createRef는 ref를 생성해 클래스형 컴포넌트에서 사용할 수 있게 합니다.
- 함수형 컴포넌트의 useRef와 동일하게 current 프로퍼티를 통해 DOM에 접근합니다.
ref의 실무 활용 사례 🛠️
1. 폼 요소의 포커스 관리
로그인 페이지에서, 페이지 로드 시 사용자 입력을 유도하기 위해 아이디 입력창에 자동 포커스를 설정할 때 사용할 수 있어요.
function LoginForm() {
const idRef = useRef(null);
React.useEffect(() => {
idRef.current.focus(); // 초기 로드 시 포커스 설정
}, []);
return (
<form>
<input ref={idRef} type="text" placeholder="아이디 입력" />
<input type="password" placeholder="비밀번호 입력" />
<button type="submit">로그인</button>
</form>
);
}
2. DOM 크기 및 위치 측정
특정 DOM 요소의 크기나 위치를 측정해야 하는 상황에서 ref를 사용할 수 있어요.
예를 들어, 모달 창의 크기를 기준으로 중앙 정렬을 할 때:
function Modal() {
const modalRef = useRef(null);
React.useEffect(() => {
const { width, height } = modalRef.current.getBoundingClientRect();
console.log(`모달 크기: ${width}px x ${height}px`);
}, []);
return <div ref={modalRef} className="modal">Hello, Modal!</div>;
}
3. 외부 라이브러리와 통합
외부 라이브러리(ex: D3, Chart.js 등)를 사용하는 경우 DOM 요소를 직접 조작해야 하는 일이 많습니다.
ref를 사용하면 React와 외부 라이브러리를 자연스럽게 통합할 수 있어요.
import React, { useRef, useEffect } from "react";
import * as d3 from "d3";
function BarChart() {
const svgRef = useRef(null);
useEffect(() => {
const svg = d3.select(svgRef.current);
svg.append("rect").attr("width", 100).attr("height", 50).attr("fill", "blue");
}, []);
return <svg ref={svgRef} width="200" height="100"></svg>;
}
ref 사용 시 주의할 점 ⚠️
- state와 역할이 다름
- state는 React가 관리하는 값으로, UI 업데이트를 트리거합니다.
- ref는 React의 렌더링 흐름에 관여하지 않고 DOM을 직접적으로 참조합니다.
- DOM 조작은 꼭 필요할 때만
- React는 가상 DOM을 통해 DOM 조작을 최적화합니다.
- 가능하면 DOM 조작을 최소화하고, React 방식으로 UI를 업데이트하세요.
- 값 변경에도 렌더링이 발생하지 않음
- ref.current 값을 변경해도 컴포넌트가 리렌더링되지 않습니다.
- UI 업데이트가 필요하다면 state를 활용해야 합니다.
ref와 관련된 주요 질문들 🙋♀️
Q1. 함수형 컴포넌트에서 ref는 렌더링을 트리거하나요?
아니요!
ref의 값이 변경되어도 React는 컴포넌트를 리렌더링하지 않습니다.
UI 업데이트가 필요하다면 state를 사용하세요.
Q2. 부모 컴포넌트에서 자식 컴포넌트에 ref를 전달할 수 있나요?
네!
React.forwardRef를 사용하면 부모 컴포넌트가 자식 컴포넌트에 ref를 전달할 수 있습니다.
const FancyInput = React.forwardRef((props, ref) => (
<input ref={ref} type="text" />
));
function Parent() {
const inputRef = useRef(null);
const focusInput = () => inputRef.current.focus();
return (
<>
<FancyInput ref={inputRef} />
<button onClick={focusInput}>포커스 이동</button>
</>
);
}
마무리: 언제 ref를 사용할까? 🎯
ref는 React의 강력한 도구지만, 모든 상황에서 사용하지는 않아야 해요.
DOM과 직접 소통하거나, 외부 라이브러리를 사용할 때와 같이 특정한 상황에서만 활용하세요.
- 해야 할 일: 포커스 제어, 크기/위치 측정, 외부 라이브러리 통합
- 하지 말아야 할 일: React의 데이터 흐름을 우회하거나, 불필요한 DOM 조작
React와 ref를 제대로 활용하면, UI와 DOM 사이의 소통이 한층 더 유연해질 거예요!
🌷전설의 개발자가 되어봅시당! 🌷
'Front-end > React' 카테고리의 다른 글
[React] render() 함수 완벽 가이드 ✨ (0) | 2024.12.06 |
---|---|
[React] React.StrictMode: 깊이 있고 알찬 완벽 가이드 🚀 (1) | 2024.12.05 |
React의 SyntheticEvent: 네이티브 이벤트와의 차이점부터 완벽 활용까지 🚀 (0) | 2024.11.28 |
이벤트 핸들링: 알아두면 일당백! 🎯 (1) | 2024.11.27 |
React의 useState: 프론트엔드 개발자를 위한 완벽 가이드 🌟 (0) | 2024.11.26 |