[react] ref 활용하기

유나니·2020년 10월 21일

react_til

목록 보기
2/2

Intro

ref특정 DOM을 직접 건드리고 싶은 경우에 지정해 사용한다. DOM을 조작할 때 getElementById 혹은 querySelector 등을 사용해 노드를 선택하고 이를 변수에 담아 활용했다. 하지만 특정 DOM을 직접 찍어 이를 활용하고 싶은 경우 ref 를 활용할 수 있다.

1. 콜백 함수를 통한 ref 설정

<input ref={(ref) => this.input=ref} /> 과 같은 형식으로 ref를 설정할 수 있다. Ref 라는 콜백함수를 props로 전달한다. 이를 통해 input 이라는 변수명을 가진 ref 가 생성된다.

간단한 validation 컴포넌트

버튼을 클릭 했을 때 input에 focus를 주도록 할 것이다. 이를 위해 input 태그를 ref로 지정하고자 한다.

import React from "react";
import './validation.css'

class Validation extends React.Component {
  state = {
    password: '',
    clicked: false,
    validated: false
  }
  handleChange = e => {
    this.setState({password: e.target.value})
  }
  handleButtonClick = () => {
    this.setState({
      clicked: true,
      validated: this.state.password === '0000'
    })
  }
  render() {
    return (
      <div>
        <input
          type="text"
          onChange={this.handleChange}
          className={this.state.clicked ? (this.state.validated ? 'success' : 'failure') : ''}
          ref={ref => this.input=ref}
        />
        <button onClick={this.handleButtonClick}>login</button>
      </div>
    )
  }
}

export default Validation
스크린샷 2020-10-21 오후 10 48 18

현재는 focus 되지 않았다. 하지만 ref로 input 태그를 지정했기 때문에 직접 접근해 login 클릭 시 focus 효과가 발동되도록 코드를 수정할 수 있다.

handleButtonClick = () => {
  this.setState({
    clicked: true,
    validated: this.state.password === '0000'
  })
  // ref에서 지정한 이름이 input 이다.
  this.input.focus()
}

2. 컴포넌트에 ref 달기

ref는 DOM에 달 수 있지만 컴포넌트에도 달 수 있다. 컴포넌트에 ref를 달게 되면 컴포넌트에 있는 내부 매서드 및 멤버 변수들에도 접근할 수 있다.

import React from "react";

class ScrollBox extends React.Component {
  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>
    )
  }
}

export default ScrollBox

다음과 같은 스크롤 컴포넌트를 만들어 보았다. 해당 컴포넌트에 다음과 같이 높이를 계산해 바닥으로 스크롤을 이동하는 매서드를 만들 수 있다. box<div ref={ref => this.box=ref}> 와 같이 ref를 설정해 직접 접근할 수 있다.

scrollToBottom = () => {
  const { scrollHeight, clientHeight } = this.box
  this.box.scrollTop = scrollHeight - clientHeight
}

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()}>go bottom</button>
      </div>
    )
  }
}

export default App;

컴포넌트를 ref로 설정하고, 이를 받아 버튼에 클릭 이벤트를 붙일 때 컴포넌트에 접근해 방금 만든 scrollToBottom 를 사용할수 있다.

3. useRef hook 사용하기

class 컴포넌트 말고 함수형 컴포넌트를 사용할 때 상태관리, lifecycle관리 등을 활용하기 위해 hook을 사용한다. Ref 역시 함수형 컴포넌트에서 사용할 때 useRef 를 사용해 쉽게 ref를 지정할 수 있다.

const Average() => {
  const inputEl = useRef(null)
  ...
  const onInsert = useCallback(() => {
		...
    ...
    inputEl.current.focus()
  }, [...])
  return (
  	<input value={num} onChange={onChange} ref={inputEl} type="text"/>
    <button onClick={onInsert}>submit</button>
  )
}

버튼 클릭 시 지정된 ref에 focus 효과를 줄 수 있다. 콜백 함수를 사용해 ref를 지정했을 때와 달리 current를 통해 해당 ref에 접근할 수 있다.

profile
User First, Mobile Friendly

0개의 댓글