본문 바로가기
Front-End/React

[리액트를 다루는 기술] 5장 ref

by Cafe Mocha 2022. 4. 29.

5장 ref: DOM에 이름 달기

  • ref(reference)
  • HTML에서 id를 사용하여 DOM에 이름을 다는 것 처럼 프로젝트 내부에서 DOM에 이름을 다는 개념.

<aside> 💡 리액트 컴포넌트에서도 id를 사용할 수는 있느나 권장하지 않습니다. 같은 컴포넌트를 여러번 사용할 경우 중복 id를 가진 DOM이 여러개 생긴다.

</aside>

  • ref는 언제 사용해야 할까?
  • DOM을 꼭 직접적으로 건드려야 할때 사용해야 한다.
  • 콜백함수를 통한 ref 설정
    <input ref={(ref)=>{this.input=ref}} />
    
    위와 같이 설정하면 앞으로 this.input은 input 요소의 DOM을 가리킵니다.
  • ref를 만드는 가장 기본적인 방법은 콜백 함수를 이용하는 것이다.
  • createRef를 통한 ref 설정 
import React, { Component } from "react";

class RefSample extends Component {
  input = React.createRef();

  handleFocus = () => {
    this.input.current.focus();
  };
  render() {
    return (
      <div>
        <input ref={this.input} />
      </div>
    );
  }
}

export default RefSample;

 

  • 컴포넌트 내부에서 멤버 변수로 React.createRef()를 담아준다.
  • 해당 멤버 변수를 ref를 달고자 하는 요소에 ref props로 넣어준다.
  • 설정한 뒤 ref를 설정해 준 DOM에 접근하려면 this.input.current를 조회 ⇒ .current를 넣어준다.
  • 컴포넌트에 ref달기
    • 컴포넌트에 ref 달기사용 방법은 DOM에 ref를 다는 것과 같습니다.
    • 리액트에서는 컴포넌트에도 ref를 달 수 있습니다. 이 방법은 주로 컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 씁니다.
// App.js
import React, { Component } from "react";
import ScrollBox from "./ScrollBox";

class App extends Component {
  render() {
    return (
      <div>
        <ScrollBox ref={(ref) => (this.scrollBox = ref)} />
        <button onClick={() => this.scrollBox.scrollToBottom()}>BOTTOM</button>
      </div>
    );
  }
}

export default App;

//ScrollBox.js
import React, { Component } from "react";

class ScrollBox extends Component {
  scrollToBottom = () => {
    const { scrollHeight, clientHeight } = this.box;
    this.box.scrollTop = scrollHeight - clientHeight;
    console.log(this.box);
  };

  render() {
    const style = {
      border: "1px solid black",
      height: "300px",
      width: "300px",
      overflow: "auto",
      position: "relative",
    };

    const innerStyle = {
      width: "100%",
      height: "650px",
      background: "linear-gradient(white,black)",
    };

    return (
      <div
        style={style}
        ref={(ref) => {
          this.box = ref;
        }}
      >
        <div style={innerStyle}></div>
      </div>
    );
  }
}

export default ScrollBox;