HTML에서 id를 사용하여 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법이 있습니다. 바로 ref(reference의 줄임말) 개념입니다
//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 (
<>
<input
type="password"
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked ? (this.state.validated ? 'success' : 'failure') : ''}
/>
<button onClick={this.handleButtonClick}>검증</button>
</>
)
}
}
export default ValidationSample
input에서는 onChange 이벤트가 발생하면 handleChange를 호출하여 state의 password 값을 업데이트하게 했습니다. button에서는 onClick 이벤트가 발생하면 handleButtonClick을 호출하여 clicked 값을 참으로 설정했고, validated 값을 검증 결과로 설정했습니다.
input의 className 값은 버튼을 누르기 전에는 비어 있는 문자열을 전달하며, 버튼을 누른 후에는 검증 결과에 따라 success 값 또는 failure 값을 설정합니다. 그리고 이 값에 따라 input 색상이 초록색 또는 빨간색으로 나타납니다.
App 컴포넌트에서 ValidationSample 컴포넌트를 불러와 렌더링해 보겠습니다.
//App.js
import React, { Component } from 'react';
import ValidationSample from './ValidationSample';
class App extends Component {
render() {
return (
<ValidationSample/>
);
}
}
export default App;
state의 사용만으로 해결할 수 없는 기능은 ref를 사용합니다.
ref의 사용은 두가지로 콜백 함수와 createRef를 통한 ref 설정입니다.
ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달해 주면 됩니다. 이 콜백 함수는 ref 값을 파라미터로 전달받습니다. 그리고 함수 내부에서 파라미터로 받은 ref를 컴포넌트의 멤버 변수로 설정해 줍니다.
<input ref={(ref) => {this.input=ref}} />
리액트에 내장되어 있는 createRef라는 함수를 사용합니다.
import React, { Component } from ‘react‘;
<input ref={(ref) => {this.input=ref}} />
class RefSample extends Component {
input = React.createRef();
handleFocus = () => {
this.input.current.focus();
}
render() {
return (
);
}
}
export default RefSample;
createRef를 사용하여 ref를 만들려면 우선 컴포넌트 내부에서 멤버 변수로 React.createRef()를 담아 주어야 합니다. 그리고 해당 멤버 변수를 ref를 달고자 하는 요소에 ref props로 넣어 주면 ref 설정이 완료됩니다.
설정한 뒤 나중에 ref를 설정해 준 DOM에 접근하려면 this.input.current를 조회하면 됩니다.
//ValidationSample.js의 input 요소
(…)
<input
ref={(ref) => this.input=ref}
(…)
/>
//ValidationSample.js - handleButtonClick 메서드
handleButtonClick = () => {
this.setState({
clicked: true,
validated: this.state.password === '0000'
});
this.input.focus();
}
코드를 수정하기 전에는 버튼을 누르면 텍스트 커서의 깜빡임이 더 이상 보이지 않았습니다. 수정 후에는 버튼을 눌러도 포커스가 input에 있는 점을 확일할 수 있습니다.
<MyComponent
ref={(ref) => {this.myComponent=ref}}
/>
MyComponent 내부의 메서드 및 멤버 변수에도 접근할 수 있습니다. 즉, 내부의 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>
);
}
}
export default ScrollBox;
//App.js
import React, { Component } from 'react';
import ScrollBox from './ScrollBox';
class App extends Component {
render() {
return (
<div>
<ScrollBox/>
</div>
);
}
}
export default App;
컴포넌트에 스크롤바를 맨 아래쪽으로 내리는 메서드를 만들겠습니다. 스크롤바를 내릴 때는 DOM 노드가 가진 다음 값들을 사용합니다.
스크롤바를 맨 아래쪽으로 내리려면 scrollHeight에서 clientHeight 높이를 빼면 됩니다.
//ScrollBox.js
import React, { Component } from 'react';
class ScrollBox extends Component {
scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
/* 앞 코드에는 비구조화 할당 문법을 사용했습니다.
다음 코드와 같은 의미입니다.
const scrollHeight = this.box.scrollHeight;
const clientHeight = this.box.cliengHeight;
*/
this.box.scrollTop = scrollHeight - clientHeight;
}
render() {
(...)
}
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;
코스 수정 이전에는 '맨밑으로' 버튼이 없었습니다.
수정 후에는 '맨밑으로' 버튼을 생성해 주면서 버튼을 누르면 스크롤바를 맨 아래쪽으로 이동할 수 있습니다.
Quiz
1. 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법 ( )이다.
2. 리액트는 DOM에 접근하지 않아도 ( )로 구현할 수 있다.
3. state의 사용만으로 해결할 수 없는 기능은 ( )를 사용한다.
4. ref를 만드는 가장 기본적인 방법으로 ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달해 주는 방식은 ( )이다.
5. ref를 사용하는 다른 방법으로 리액트에 내장되어 있는 ( )를 사용한다.
6. 리액트에서는 ( )에도 ref를 달 수 있다.
7. ( )는 스크롤이 있는 박스의 높이를 나타낸다.
8. '5.1.1 예제 컴포넌트 생성'의 ValidationSample.js에 ref를 적용해본다.
9. '5.3.3 컴포넌트에 메서드 생성'의 ScrollBox.js에 ref를 적용해본다.
Corner React3
Editor: 케이비
[리액트 스타터 3] 7장. 컴포넌트의 라이프 사이클 메서드 (0) | 2022.11.17 |
---|---|
[리액트 스타터 3] 6장. 컴포넌트 반복 (0) | 2022.11.10 |
[리액트 스타터 3] 4장. 이벤트 핸들링 (0) | 2022.10.13 |
[리액트 스타터 3] 3장. 컴포넌트 (0) | 2022.10.06 |
[리액트 스타터 3] 2장. JSX (1) | 2022.09.29 |