ref

한상현·2021년 1월 24일
0

React

목록 보기
3/12

일반적인 HTML에서 DOM요소에 이름을 달 때는 id를 사용한다.
그렇다면 리액트 프로젝트 내부에서는 DOM에 이름을 어떻게 달까? =>ref

🧨리액트 컴포넌트 안에서는 id 사용 불가능?

리액트 컴포넌트 안에서도 id를 사용할 수 있다고 한다. 그러나 HTML에서 DOM의 id는 유일해야 하는데, 이런 상황에서는 중복 id를 가진 DOM이 여러 개 생기므로 특수한 경우가 아니면 사용을 권장하지 않는다고 한다!!

🎈ref는 언제 사용?

ref는 "DOM을 직접적으로 건드려야 할 때" 사용.

ValidationSample.js
class ValidationSample extends 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="password"
                value = {this.state.password}
                onChange = {this.handleChange}
                className={this.state.clicked?(this.state.validated ? 'success':'failure'):''}
                />
                <button onClick={this.handleButtonClick}>검증하기</button> 
            </div>
        );
    }
}
ValidationSample.css
.success{
    background-color:lightgreen;
}

.failure{
    background-color:lightcoral;
}
  • onChange로 사용자가 비밀번호를 입력할때마다 state의 password값을 갱신.
  • render 안에서 className을 state의 clicked의 bool값으로 판단.
    • bool == true : state의 validated 값에 따라 success, failure로 className 갱신.
    • bool == false : className을 ''로 갱신.
  • 그렇다면 validated 값은?? handleButtonClick함수로 만들어주었다. clicekd의 값을 true로 validated의 값은 0000이면 true 그렇지 않다면 false로 갱신해줬다.
  • className이 success냐 failure이냐에 따라 input의 색상을 바꿔준 것.

🧨DOM을 꼭 사용해야 하는 상황

앞 예제는 state를 사용하여 필요한 기능을 구현했다.
그러나 state로 불가능한 기능이 있다면?

  • 특정 input에 포커스 주기.
  • 스크롤 박스 조작하기.
  • Canvas 요소에 그림 그리기.

이러한 상황에서는 DOM에 직접적으로 접근해야 하므로 ref를 사용해준다.

🎈ref 사용

ref를 달아야 하는 DOM에 ref 속성을 추가할 때는 props를 설정하듯이 하면 된다. ref 값으로는 콜백 함수를 전달한다.
콜백 함수는 ref를 파라미터로 가지며, 콜백 함수 내부에서 컨포넌트의 멤버 변수에 ref를 담는 코드를 작성한다.

<input ref={(ref) => {this.input=ref}}></input>

이렇게 선언해주면 this.input은 input 요소의 DOM을 가리킨다.
🧨DOM 타입과 관계없이 ref의 이름은 자유롭게 지정 가능!!

Validationsample.js
<input type="password"
 	ref={(ref)=>this.input=ref}
    ...

handleButtonClick = () =>{
        this.setState({
            clicked:true,
            validated:this.state.password==='0000'
        })
        this.input.focus();
    }    

버튼을 누르면 포커스가 input으로 넘어가는 코드.

🎈컴포넌트에 ref 달기

사용법

<MyComponent ref={(ref) => {this.myComponent=ref}} />

MyComponent 내부의 메서드 및 멤버 변수에도 접근이 가능.

myComponent.handleClick, myComponent.input 등등

🧨이벤트 처리

<button onClick={() => this.scrollBox.scrollToBottom()}>
<button onClick={this.scrollBox.scrollToBottom()}
  • 문법 상으로 onclick={this.scrollBox.scrollToBottom()로 작성해도 틀린 것은 아니다.
  • 허나 컴포넌트가 처음 렌더링될 때는 this.scrollBox 값이 undefined이므로 this.scrollBox.scrolltoBottom 값을 읽어오는 과정에서 오류가 발생한다.
  • 그러므로 화살표 함수 문법을 사용하여 아예 새로운 함수를 만들고 그 내부에서 this.scrollBox.scrollToBottom 값을 읽어 와서 실행하므로 오류가 발생하지 않는다.

정리

  • 컴포넌트 내부에서 DOM에 직접 접근해야 할 때 ref를 사용.
  • 굳이 ref를 사용하지 않아도 되는지 고려하고 사용하기!!😀

참고 : <리액트를 다루는 기술>

profile
의 공부 노트.

0개의 댓글