Ref를 통해 특정한 virtual Dom element에 접근
Ref는 render() 함수로 인해 생선된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공한다.
JavaSript에서는 getElementById, querySelector와 같은 메서드로 특정 엘리먼트에 접근할 수 있다.
하지만 React에서는 가상 DOM을 사용하기 때문에 렌더링이 종료되기 전 페이지의 element가 존재하지 않아 위와 같은 방법을 사용할 수 없다.
그래서 Ref를 통해 작업자가 원하는 요소에 접근한다.
Ref는 다음과 같은 경우에 사용할 수 있다.
Focus, Text의 영역 선택, Media 재생 관리
Animation을 직접 실행
서드 파티 DOM 라이브러리를 React와 같이 사용
Ref를 생성하는 방법은 다음과 같다.
React.createRef()를 통해 Ref를 생성한 뒤 변수에 담는다.
해당 엘리먼트의 ref 어트리뷰트를 추가한다.
Ref를 담은 변수를 추가한 어트리뷰트에 적용한다.
보통, 컴포넌트의 인스턴스가 생성될 때 Ref를 추가하여 인스턴스의 모든 곳에서 Ref에 접근이 가능하게 한다.
class RefExample extends React.Component {
constructor(props) {
super(props);
this.examRef = React.createRef();
}
render() {
return <input ref={this.examRef} />;
}
}
render() 함수 안에서 ref가 엘리먼트에게 전달되면 current 어트리뷰트에 노드를 향한 참조가 전달된다.
// <input ref={this.examRef} />의 참조가 전달된다.
const node = this.examRef.current;
이 때 ref 어트리뷰트가 HTML 엘리먼트에 사용됬다면 자신을 전달받은 DOM 엘리먼트를 current 프로퍼티로 전달한다.
반대로 개발자가 작성한 컴포넌트에 사용됬다면 마운트된 컴포넌트의 인스턴스를 current 프로퍼티로 전달한다.
또한 함수 컴포넌트(Hook)는 인스턴스가 존재하지 않아 ref 어트리뷰트를 사용할 수 없다.
하지만 예외로 DOM 엘리먼트, 클래스 컴포넌트의 인스턴스에 접근하기 위해 ref 어트리뷰트를 사용하는 것은 가능하다.
class NicknameEditForm extends React.Component {
constructor(props) {
super(props);
this.text = React.createRef();
}
// render() 함수가 처음 실행된 뒤 input에 focus
componentDidMount() {
this.text.current.focusTextInput();
}
render() {
return (
<NicknameInput ref={this.text} />
);
}
}
function NicknameInput() {
return <input />;
}
class NicknameEditForm extends React.Component {
constructor(props) {
super(props);
this.text = React.createRef();
}
render() {
// 함수 컴포넌트는 인스턴스가 없기 때문에 ref 어트리뷰트를 사용할 수 없다.
return (
<NicknameInput ref={this.text} />
);
}
}