(React) Ref

Mirrer·2022년 8월 13일
0

React

목록 보기
8/15
post-thumbnail

Ref

Ref를 통해 특정한 virtual Dom element에 접근

Refrender() 함수로 인해 생선된 DOM 노드React 엘리먼트에 접근하는 방법을 제공한다.

JavaSript에서는 getElementById, querySelector와 같은 메서드로 특정 엘리먼트에 접근할 수 있다.

하지만 React에서는 가상 DOM을 사용하기 때문에 렌더링이 종료되기 전 페이지의 element가 존재하지 않아 위와 같은 방법을 사용할 수 없다.

그래서 Ref를 통해 작업자가 원하는 요소에 접근한다.


Ref를 사용하는 경우

Ref는 다음과 같은 경우에 사용할 수 있다.

  • Focus, Text의 영역 선택, Media 재생 관리

  • Animation을 직접 실행

  • 서드 파티 DOM 라이브러리React와 같이 사용


Ref 사용방법

Ref 생성

Ref생성하는 방법은 다음과 같다.

  1. React.createRef()를 통해 Ref를 생성한 뒤 변수에 담는다.

  2. 해당 엘리먼트의 ref 어트리뷰트를 추가한다.

  3. Ref를 담은 변수를 추가한 어트리뷰트에 적용한다.

보통, 컴포넌트의 인스턴스가 생성될 때 Ref를 추가하여 인스턴스의 모든 곳에서 Ref에 접근이 가능하게 한다.

class RefExample extends React.Component {
  constructor(props) {
    super(props);
    this.examRef = React.createRef();
  }
  render() {
    return <input ref={this.examRef} />;
  }
}

Ref 접근

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} />
    );
  }
}

참고 자료

React 공식문서
웹 게임을 만들며 배우는 React - 제로초

profile
memories Of A front-end web developer

0개의 댓글