<div id="my-element"></div>
특정 DOM 요소에 어떤 작업을 해야 할 때 HTML에서 id를 사용해 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법
DOM을 꼭 직접적으로 건드려야 할 때
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에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림 그리기
사용하는 방법은 두 가지
ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달한다.
이 콜백 함수는 ref 값을 파라미터로 전달 받고 함수 내부에서 파라미터로 받은 ref를 컴포넌트의 멤버 변수로 설정해준다.
<input ref={(ref) => {this.input=ref}} />
위와 같이 하면 this.input은 input 요소의 DOM을 가리킨다.
ref의 이름은 원하는 것으로 지정가능 this.이름 = ref
리액트에 내장되어 있는 createRef
함수 사용 ( v16.3 부터 도입)
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;
ref를 설정해 준 DOM에 접근하려면 this.input.current
를 조회한다.
주로 컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 쓴다.
<MyComponent
ref={(ref) => {this.myComponent=ref}}
/>
MyComponent 내부의 메서드 및 멤버 변수에도 접근할 수 있게 된다.
실습 진행 순서
1. ScrollBox 컴포넌트 만들기
2. 컴포넌트에 ref 달기
3. ref를 이용하여 컴포넌트 내부 메서드 호출하기
// ScrollBox.js
import React, { Component } from "react";
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>
</div>
);
}
}
export default ScrollBox;
최상위 DOM에 ref를 달아 준다.
컴포넌트에 스크롤바를 맨 아래쪽으로 내리는 메서드 scrollToBottom을 생성할 것
scrollTop
: 세로 스크롤바 위치(0~350)scrollHeight
: 스크롤이 있는 박스 안의 div 높이(650)clientHeight
: 스크롤이 있는 박스의 높이(300) scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
this.box.scrollTop = scrollHeight - clientHeight;
};
App 컴포넌트에서 ScrollBox에 ref를 달고 버튼을 만들어 누르면, ScrollBox 컴포넌트의 scrollToBottom 메서드를 실행하도록 한다.
// App.js
import ScrollBox from "./ScrollBox";
import { Component } from "react";
class App extends Component {
render() {
return (
<div>
<ScrollBox ref={(ref) => (this.scrollBox = ref)} />
<button
onClick={() => {
this.scrollBox.scrollToBottom();
}}
>
맨 밑으로
</button>
</div>
);
}
}
export default App;
주의사항
onClick={this.scrollBox.scrollToBottom}
로 작성해도 틀린 것은 아니다.
하지만 컴포넌트가 처음 렌더링될 때는this.scrollBox
값이undefined
이므로 this.scrollBox.scrollBottom 값을 읽어오는 과정에서 오류가 발생한다.
화살표 함수 문법을 사용해 아예 새로운 함수를 만들고 그 내부에서 메서드를 실행하면, 버튼을 누를 때 (이미 한번 렌더링해서this.scrollBox
를 설정한 시점)this.scrollBox.scrollToBottom
값을 읽어 와서 실행하므로 오류가 발생하지 않는다.