yeon
yeon I am a Korean web programmer with bboy dancing as a hobby. :)

Ref 와 DOM

Ref 와 DOM

Ref 와 DOM

Ref는 render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공한다.

Ref 사용

  • 포커스, 텍스트 선택영역, 미디어 재생관리, 파일데이터 관리
  • 애니메이션 실행
  • 서드파티 DOM 라이브러리를 React와 같이 사용할때

Ref를 사용하기 전에는 정말 사용이 필요한 것인지 확인 후 사용하는 것이 좋다. 예로는 Ref를 사용하여 Dialog와 같은 Element를 DOM에 직접 접근하여 style display none을 변경해주며 노출 여부를 제어하는 것 보다는 isOpen 형태로 상태값을 만들어 제어하는 것이 바람직하다.

ex)

ref를 사용하는 잘못된 예

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Dialog extends React.Component {
  constructor(props) {
    super(props);
    this.ref = React.createRef();
    this.onOpen = this.onOpen.bind(this);
    this.onClose = this.onClose.bind(this);
  }

  onOpen() {
    this.ref.current.style.display = '';
  }

  onClose() {
    this.ref.current.style.display = 'none';
  }

  render() {
    return (
      <div>
        <div ref={this.ref}>Dialog</div>
        <button onClick={this.onOpen}>open</button>
        <button onClick={this.onClose}>close</button>
      </div>
    );
  }
}

위와 같은 경우에는 isOpen state로 관리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Dialog extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isOpen: false
    };
    this.onOpen = this.onOpen.bind(this);
    this.onClose = this.onClose.bind(this);
  }

  onOpen() {
    this.setState({isOpen: true})
  }

  onClose() {
    this.setState({isOpen: false});
  }

  render() {
    return (
      <div>
        {this.isOpen && <div ref={this.ref}>Dialog</div>}
        <button onClick={this.onOpen}>open</button>
        <button onClick={this.onClose}>close</button>
      </div>
    );
  }
}

React는 상태값 변경에 따른 랜더링을 하는 것이 주요 데이터 흐름이다. 이때 Ref를 무분별하게 사용하여 DOM의 상태를 임의로 변경하는 것은 개발자가 예상하지 못한 흐름으로 확장될 수도 있다. 단방향 데이터 흐름으로 인한 데이터 추적 및 관리가 강점인 React에서 Ref 사용시 주의해야하는 이유이다.



Ref 함수 컴포넌트

위의 예제에서 사용한 React.createRef()는 클래스 컴포넌트에서만 사용이 가능하다. 함수 컴포넌트의 경우에는 useRef 훅을 사용하여 ref를 설정하여 DOM에 직접 접근 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function CustomTextInput(props) {
  // textInput은 ref 어트리뷰트를 통해 전달되기 위해서
  // 이곳에서 정의되어야만 합니다.
  const textInput = useRef(null);

  function handleClick() {
    textInput.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} />
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}



[Ref] :




comments powered by Disqus