'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;
앞 예제에서는 state를 사용하여 우리에게 필요한 기능을 구현했지만, 가끔 state만으로 해결할 수 없는 기능이 있습니다. 어떤 상황인지 알아볼까요?
1)특정 input에 포커스 주기
2)스크롤 박스 조작하기
3)Canvas요소에 그림 그리기
이때는 어쩔 수 없이 DOM에 직접적으로 접근해야 하는데, 이를 위해 바로 ref를 사용합니다.
1.콜백 힘수를 통한 ref 설정
ref를 만드는 가장 기본적인 방법은 콜백 함수를 사용하는 것입니다. ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달해 주면 됩니다. 이 콜백함수는 ref 값을 파라미터로 전달받습니다. 그리고 함수 내부에서 파라미터로 받은 ref를 컴포넌트의 멤버 변수로 설정해 줍니다.
이렇게 하면 앞으로 this.input은 input 요소의 DOM을 가리킵니다. ref의 이름은 원하는 것으로 자유롭게 지정할 수 있습니다. DOM 타입과 관계없이 this.superman=ref처럼 마음대로 지정합니다.
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;
ScrollBox.js
import React, { Component } from "react";
class ScrollBox extends Component {
scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
this.box.scrollTop = scrollHeight - clientHeight;
};
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;
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()}>
맨 밑으로
</button>
</div>
);
}
}
export default App;