당니의 개발자 스토리
[리액트/LG CNS AM Inspire Camp 1기] ref란 무엇일까? - 당니의 개발자 스토리 본문
[리액트/LG CNS AM Inspire Camp 1기] ref란 무엇일까? - 당니의 개발자 스토리
clainy 2025. 1. 6. 03:231/3 수업 시간에 다룬 ref에 대해서 review 할 것이다.
ref란?
참조(reference)의 줄임말로, DOM 요소나 컴포넌트에 직접 접근할 수 있게 해주는 참조값 이다.
즉, 특정 DOM 요소나 React 컴포넌트를 가리킬 수 있는 참조를 제공한다고 생각하면 쉽다. 이 ref를 통해 직접 접근이 가능해진다.
ref는 언제 사용할까?
리액트에서는 상태(state), 속성(props)를 사용해서 사용자 인터페이스(UI)를 업데이트 한다. 그리고 이 값들이 바뀔 때마다 컴포넌트가 리렌더링 되는데, 이렇게 불필요한 리렌더링이 발생하면 성능에 부담이 된다.
import React, { useState } from 'react';
function InputComponent() {
const [text, setText] = useState(''); // 'text'는 상태 값, 'setText'는 상태 값을 변경하는 함수
return (
<input
type="text"
value={text} // input의 값은 'text' 상태 값
onChange={(e) => setText(e.target.value)} // input 값이 변경될 때마다 리렌더링 발생
/>
);
}
이렇게 state로 관리하면 input 값의 text가 변경될 때마다 불필요한 리렌더링이 발생한다.
이러한 문제를 해결하기 위해서 input에 state 대신, ref를 사용한다면
import React, { useRef } from 'react';
function InputComponent() {
const inputRef = useRef();
const handleChange = () => {
console.log(inputRef.current.value); // ref로 직접 접근해서 값을 가져옴
};
return (
<div>
<input
ref={inputRef}
type="text"
onChange={handleChange} // state를 사용하지 않고 ref로 직접 값 관리
/>
</div>
);
}
위와 같이 useRef를 사용하면, state로 관리하지 않고 DOM 요소에 직접 접근할 수 있게 되어, input 값이 변경돼도 리렌더링 되지 않는다.
ref의 사용 사례
- 포커스, 텍스트 선택 영역, 혹은 미디어의 재생을 관리할 때
- 특정 Element의 크기를 가져와야 하는 경우
- 애니메이션을 직접 실행할 때
- 서드 파티 DOM 라이브러리를 React와 같이 사용할 때
위처럼 직접적으로 DOM 요소를 다뤄야하는 경우, 상태(state)나, 속성(props) 대신 ref를 사용하면 리렌더링을 피할 수 있다.
ref 사용 방법
ref를 사용하는 방법에는 두 가지가 있다.
1. createRef()를 이용하는 방법 : 클래스형 컴포넌트에서 사용, React 16.3 버전에 추가되었다.
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef(); // 1. ref 객체 생성
}
render() {
return <input ref={this.myRef}/>; // 2. input에 ref 연결
}
handler = () => {
const node = this.myRef.current; // 3. ref로 input에 접근
node.focus(); // 4. input에 포커스를 설정
}
}
입력창 컴포넌트를 만드는 코드이다. 위와 같이 createRef()로 ref 객체를 생성한다.
render()는 input 요소를 렌더링하고 input에다가 ref={this.myRef}를 연결해준다.
import { Component, createRef } from "react"; // React와 createRef를 임포트
class MyComponent extends Component {
constructor(props) {
super(props); // 부모 클래스인 Component의 constructor 호출
this.myRef = createRef();
// 1. ref 객체 생성: createRef()로 ref를 생성하여 this.myRef에 할당
}
render() {
return (
<>
<input ref={this.myRef} /> {
/* 2. input 요소에 ref를 설정하여 this.myRef.current로 접근 가능 */
}
<button onClick={this.handler}>포커스전달</button> {
/* 3. 버튼을 클릭하면 handler 함수가 실행 */
}
</>
);
}
handler = () => {
const node = this.myRef.current; // 4. this.myRef.current로 input 요소를 참조(접근)
node.focus(); // 5. input에 포커스를 설정
}
}
function App() {
return <MyComponent />; // MyComponent를 화면에 표시
}
export default App; // App을 외부로 내보내기
버튼을 클릭하면 포커스를 전달하는 코드이다.
2. 콜백 함수로 ref 설정
ref 어트리뷰트에 React.createRef()를 통해 생성된 ref를 전달하는 대신, 함수를 전달한다.
React 컴포넌트의 인스턴스나 DOM 요소를 콜백 함수의 인자로 받아서 직접 제어할 수 있다.
<input ref={ x => this.myInput = x } />
~~~~~~~~~~~~
이 변수를 이용해서 <input> 요소를 직접 제어하는 것이 가능하다.
예) this.myInput.focus();
보면 콜백 함수가 ref에 전달되고 있다. x는 input DOM 요소 이다.
input 요소를 this.myInput이라는 변수에 저장해서 반환하는 함수를 ref에 전달한다.
import { Component } from "react"; // React Component 클래스를 가져옵니다.
class MyComponent extends Component {
// 컴포넌트의 state 초기화
state = {
message: "" // message라는 상태 변수를 정의, 기본값은 빈 문자열
};
// 버튼 클릭 시 실행되는 핸들러
handler = () => {
// ref로 받은 input DOM 요소에 직접 접근
const node = this.myRef;
// focus() 메서드를 호출하여 input 요소에 포커스를 설정
node.focus();
}
render() {
return (
<>
<input
ref={x => {
this.myRef = x; // input DOM 요소를 this.myRef에 저장
console.log(x); // 콘솔에 input 요소를 출력 (개발 중 디버깅 용도)
}}
onChange={e => this.setState({ message: e.target.value })}
// onChange 이벤트로 input 값이 바뀔 때마다 message 상태 값을 업데이트합니다.
</>
<button onClick={this.handler}>포커스전달</button>
<!-- 버튼 클릭 시 handler() 함수가 실행되어 input 요소에 포커스를 설정 -->
</>
);
}
}
function App() {
// MyComponent 컴포넌트를 화면에 렌더링
return <MyComponent />;
}
export default App; // App 컴포넌트를 다른 파일에서 사용할 수 있도록 내보냄
ref는 왜 current로 접근해야 할까?
ref는 객체 인데, ref 객체에는 current 라는 프로퍼티가 존재한다. 이 프로퍼티에 실제 DOM 요소나 컴포넌트 인스턴스가 저장된다.
handler = () => {
const node = this.myRef.current; // 4. this.myRef.current로 input 요소를 참조(접근)
node.focus(); // 5. input에 포커스를 설정
}
실제로 콘솔로 myRef를 찍어보면, 렌더링 이전에는 { current : null } 이 보일 것이다.
'LG CNS > RealVerse 스터디' 카테고리의 다른 글
| 기술면접 대비# 네트워크의 기초: 네트워크, 트래픽, 처리량, 대역폭, RTT (0) | 2025.02.05 |
|---|---|
| [기술 면접 대비] 좋은 객체 지향이란? - 스프링의 핵심 컨셉, SOLID (0) | 2025.01.09 |
| [LG CNS AM Inspire Camp 1기] AM이란 무엇일까? 역사, MSA, Agile - 당니의 개발자 스토리 (15) | 2025.01.06 |