리액트를 다루는 기술 : useRef

김명성·2022년 3월 20일
0

useRef


일반 HTML + Javascript에서는 Dom요소를 조작하여야 할 때 조작할 HTML tag에 id를 부여하고 Javscript를 통해 DOM 요소를 조작한다.
react.js에서도 ref(reference)를 통해 이름을 달아 HTML 요소를 제어할 수 있다.
react components(JSX) 안에서 id대신 ref를 통해 DOM 요소를 다루는 이유는 다른 라이브러리나 프레임워크를 사용할 때 공동의 id가 발생할 수 있으며, 이러한 점은 오류의 원인이 된다.
다만 ref는 DOM을 직접 건드려야 할 때 사용한다.

ref 사용 없이 state만으로 상태를 변경하는 예시.

class Validation extends Component {
  state = {
    password: '',
    clicked: false,
    validated: false,
  };
//input의 변화를 감지하여 값을 얻게하는 handleChange 함수
  handleChange = (e: any) => {
    this.setState({
      password: e.target.value,
    });
  };
 
  handleButtonClick = () => {
    this.setState({
      clicked: true,
      validated: this.state.password === '0000',
    });
  };
	render() {	
      return (
      <div>
		<div>	
		<input
		type="password"
		value={this.state.password}
        onChange={this.handleChange}
//state의 clicked와 validated의 변화하는 boolean 값을 통해 다른 색상을 갖게 하였다. 
		style={
		{backgroundColor: this.state.clicked
		? this.state.validated
		? 'lightgreen'
		: 'orangered'
		: ''}
        	}
    	/>
    <button onClick={this.handleButtonClick}>검증하기</button>
    </div>
 );
  }
}

가끔은 state만으로 해결할 수 없는 기능들이 있다.

- 특정 input에 focus를 주어야하는 상황
- 스크롤박스를 조작해야 하는 상황
- Canvas 요소에 그림을 그려야 하는 상황
여러개의 동일한 DOM 중 하나의 DOM 상태를 변경해야 하거나, DOM의 위치에 따라 상태의 변화가 일어나야 할 때 ref를 사용한다.

ref를 사용하는 방법

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

ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달해준다.
콜백함수는 ref의 값을 파라미터로 전달받고, 함수 내부에서 파라미터로 전달 받은 ref의 값을 컴포넌트의 멤버 변수로 설정해준다.
<input ref={(ref) => {this.regacyInput=ref}}/>

2.createRef를 통한 ref 설정

리액트에 내장되어 있는 createRef라는 함수를 사용하여 더 적은 코드로 쉽게 사용할 수 있다.
먼저 클래스형 컴포넌트 내부의 맴버 변수로 createRef를 선언한다.
input:React.RefObject<HTMLInputElement> = React.createRef();
그리고 해당 맴버 변수를 ref로 필요로 하는 요소에 props로 전달하면 ref 설정이 완료된다.

요소에 ref를 props로 전달한 뒤, 조작하기 위해서는 this.input.current를 통해 조작할 수 있는데, 버튼을 클릭하면 focus가 되는 방법을 예시로 만들어보자면

...
// 버튼을 클릭하면 input에 focusing 되는 함수. 옵셔널 체이닝은 ts.
handleFocus = () =>{
      this.input.current?.focus();
  }
<input ref={this.input}/>
<button onClick={this.handleFocus}>인풋포커스</button>

콜백 함수와 다른점은 뒷 부분에 this.input 다음에 current를 넣어주어야 한다는 것이다.

첫번째 예시의 state를 통한 조작과, 2번째 useRef를 조합하여 보다 더 나은 UX를 추구할 수 있다.

password가 0000이 아니라면, input에 focus 주기.
import React, { Component } from 'react';

class Validation extends Component {
    
  state = {
    password: '',
    clicked: false,
    validated: false,
  };
  regacyInput:any;
  input:React.RefObject<HTMLInputElement> = React.createRef();
  handleFocus = () =>{
      
     
    
  }
  handleChange = (e: any) => {
    this.setState({
      password: e.target.value,
    });
  };

  handleButtonClick = () => {
    this.setState({
      clicked: true,
      validated: this.state.password === '0000',
    });
    this.input.current?.focus();
  };
  render() {
    return (
      <>
      <div>
        <input
        ref={this.input}
          type="password"
          value={this.state.password}
          onChange={this.handleChange}
          style={
            {backgroundColor: this.state.clicked
              ? this.state.validated
                ? 'lightgreen'
                : 'orangered'
              : ''}
          }
        />
        <button onClick={this.handleButtonClick}>검증하기</button>
      </div>      
      </>
    );
  }
}

export default Validation;

0개의 댓글