HTML
에서 id
를 사용하여 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법을 뜻한다.id
를 달면 css
에서 특정 id
에 특정 스타일을 적용하거나 자바스크립트에서 해당 id
를 가진 요소를 찾아 작업할 수 있다.리액트 컴포넌트안에서
id
를 사용할 수 있다. JSX 안에서 DOM에id
를 달면 해당 DOM을 렌더링할 때 그대로 전달되지만 권장하지 않는다고 함.
👉 예를 들어,HTML
에서DOM
의id
는 유일해야 하는데, 같은 컴포넌트를 여러 번 사용하게 되면 중복id
를 가진 DOM이 여러 개 생기기 때문에 권장하지 않는다.
ref
를 사용해보자.src/ValidationSample.css
와 src/ValidationSample.js
파일 생성 후 아래와 같이 코드를 작성했다.//ValidationSample.css
.success {
background-color: lightgreen;
}
.failure {
background-color: lightcoral;
}
//ValidationSample.js
import React, {Component} from "react";
import './ValidationSample.css'
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>
);
}
}
export default ValidationSample;
input
에서 onChange 이벤트가 발생하면 handleChange를 호출하여 state
의 password
값을 업데이트 하는 코드이다.button
에서는 onClick 이벤트가 발생하면 handleButtonClick을 호출하여 clicked
값을 참으로 설정했고, validated
값을 검증 결과로 설정했다.input
의 className 값은 버튼을 누르기 전에 비어있는 문자열
을 전달하고, 버튼을 누른 후에는 검증 결과에 따라 success
, failure
값을 설정하여 input
색상이 초록색
또는 빨간색
으로 나타난다.state
를 사용하여 필요한 기능을 구현했지만, 다음과 같이 state
만으로 해결할 수 없는 기능이 있다.input
에 포커스 주기ref
를 사용해야 한다.ref
를 사용하는 방법은 두 가지로 나뉜다.요소
에 ref
라는 콜백 함수를 props
로 전달하여 사용한다.ref
값을 파라미터로 전달받고, 함수 내부에서 파라미터
로 받은 ref
를 컴포넌트의 멤버 변수로 설정한다.//콜백 함수 예시
<input ref={(ref) => {this.input=ref}} />
this.input
은 input 요소의 DOM을 가르킨다.ref
의 이름은 원하는 것으로 자유롭게 설정할 수 있다. (ex. this.dekay = ref
)import React, { Component } from "react";
class ValidationSample extends Component {
input = React.createRef();
handleFocus = () => {
this.input.current.focus();
}
render () {
return (
<div>
<input ref={this.input} />
</div>
);
}
}
export default ValidationSample;
ref
를 만들기 위해서는 컴포넌트 내부에서 멤버 변수
로 React.createRef()를 담아주어야 한다.멤버 변수
를 ref를 달고자 하는 요소에 ref props
로 넣어주면 ref 설정이 된다.this.input.current
를 조회하면 된다.ValidationSample.js
를 렌더링 해보면 검증 하기를 눌렀을 때 input 요소
의 텍스트 커서가 더 이상 보이지 않는다.//ValidationSample.js
(...)
<input
ref={(ref) => this.input=ref}
(...)
/>
import React, {Component} from "react";
import './ValidationSample.css'
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'
})
this.input.focus();
}
render() {
return (
<div>
<input
ref={(ref) => this.input=ref}
type="password"
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked ? (this.state.validated ? 'success' : 'failure') : ''}
/>
<button onClick={this.handleButtonClick}>검증하기</button>
</div>
);
}
}
export default ValidationSample;
input 요소
를 가르키고 있기 때문에 일반 DOM을 다루듯이 위의 코드 처럼 작성하면 된다.ref
를 다는 방법은 DOM에 ref를 다는 방법과 같다.<MyComponent
ref={(ref) => {this.myComponent=ref}}
/>
메서드
및 멤버 변수
에 접근할 수 있다.ref
에도 접근할 수 있다.myComponent
, handleClick
, input
등)ref
를 다는 것이 익숙하지 않아서 간단한 예제를 만들어 보려고 한다.컴포넌트
를 하나 만들고, 스크롤바 아래로 내리는 작업을 부모 컴포넌트
에서 실행해 보자.scr/ScrollBox
라는 컴포넌트를 만들어 JSX의 인라인 스타일링 문법으로 스크롤 박스를 생성했고, 최상위 DOM에 ref
를 달았다.//ScrollBox.js
class ScrollBox extends 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>
)
}
}
스크롤바
를 맨 아래쪽으로 내리는 메서드를 생성해보자.스크롤바
를 내릴 때는 DOM 노드가 가진 다음 값들을 사용했다.//ScrollBox.js
class ScrollBox extends Component {
scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
this.box.scrollTop = scrollHeight - clientHeight;
}
render() {
(...)
}
}
scrollToBottom
메서드의 첫 번째 줄에서는 계속 언급한대로 ES6의 비구조화 할당 문법을 사용한 것이다.ScrollBox
에 ref
를 달고 버튼을 만들어서 누르면, ScrollBox
컴포넌트의 scrollToBottom 메서드를 실행하도록 코드를 작성했다.//App.js
class App extends Component {
render() {
return (
<div>
<ScrollBox ref={(ref) => (this.scrollBox = ref)} />
<button onClick={() => this.scrollBox.scrollToBottom()}>
맨 밑으로
</button>
</div>
);
}
}
3.2.3 절
코드에서 문법상으로는 onClick={this.scrollBox.scrollToBottom}
와 같은 형식으로 해도 틀린것은 아니다.this.scrollBox
값이 undefined
이므로 this.scrollBox.scrollToBottom
값을 인식하지 못하는 오류가 발생할 수 있다.this.scrollBox.scrollToBottom
메서드를 실행하는 것 처럼 사용하자.this.scrollBox
를 설정한 시점이라 오류가 발생안함.✔