ref는 언제사용할까?
Dom에 직접적으로 접근해야하는 상황이라고한다.
1. state로 상태변화 rendering하기
우선 값 변화에따라 state를 사용해서 만든 소스를 구현해보자
import { 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 = (e) => {
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'
: ''
}
></input>
<button onClick={this.handleButtonClick}>검증하기</button>
</div>
);
}
}
export default ValidationSample;
이렇게 값이 변하고, 변한값을 검증하는과정을 state로 구현할수있지만
state로 구현할수없는 상황도 있다고한다
1. 특정 input에 포커스주기
2. 스크롤 박스 조작하기
3. Canvas요소에 그림 그리기 등
2. 콜백 함수를 통한 ref 설정
ref를 만드는 가장 기본적인 방법은 콜백함수를 사용하는 것이다.
<input
ref={(ref) => {
this.input = ref;
}}
></input>;
이렇게 ref를 달고하자는 요소에 ref라는 콜백함수를 props로 전달해주면된다.
이콜백함수는 ref를 파라미터로 전달받고, 함수 내부에서 파라미터로 받은 ref를 컴포넌트의 멤버 변수로 설정해준다.
3. createRef를 통한 ref 설정
ref를만드는 또 다른 방법은 리액트에 내장되이는 createRef라는 함수를 사용한다.
우선 콜백함수로 사용하는 방식을 좀더보고자 넘어간다.
4. 컴포넌트에 ref 달기
리액트에서는 컴포넌트에도 ref를 달수있다.
스크롤 박스가있는 컴포넌트를 만들고, 스크롤바를 아래로 내리는 작업을 부모 컴포넌트에서 실행해보겟다.
import { 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;
그후 상위 컴포넌트에 onClick 이벤트와, ref 를 선언해준다
import { Component } from 'react';
import ScrollBox from './ScrollBox';
class App extends Component {
render() {
return (
<div>
<ScrollBox ref={(ref) => (this.scrollBox = ref)}></ScrollBox>
<button onClick={() => this.scrollBox.scrollToBottom()}>
맨 밑으로
</button>
</div>
);
}
}
export default App;
import { Component } from 'react';
class ScrollBox extends Component {
scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
// 비구조화할당 const scrollHeigt = this.box.scrollHeight 같다
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>
</div>
);
}
}
export default ScrollBox;
그후 버튼클릭시 scrollToBottom() 메서드를 선언해주었다.
맨빝으로 버튼을 누르면 맨아래로 이동하는것을 알수있다.
정리
컴포넌트에서 DOM에 직접 접근해야할때 ref를 사용한다.
만약 서로다른 컴포넌트끼리 데이터를 교류한다면? ref를 사용할순있지만 리액트사상에 어긋난 설계이다.
그건 나중에 리덕스와 Context API를 사용해서 효율적으로 교류하게될겄이다.
아직 함후컴포넌트에서 ref를 사용하지않았다. 함수컴포넌트에서는 useRef라는 Hook 함수를 사용한다 나중에 보고
다음장에서는 컴포넌트의 반복에대해서 알아보자
'Book' 카테고리의 다른 글
[리액트를 다루는 기술] 8. 컴포넌트 스타일링 (0) | 2022.07.03 |
---|---|
[리액트를 다루는 기술] 7. 컴포넌트의 반복 (0) | 2022.07.03 |
[리액트를 다루는 기술] 5. 이벤트 핸들링 (0) | 2022.07.02 |
[리액트를 다루는 기술] 4. 컴포넌트 (0) | 2022.06.27 |
[리액트를 다루는 기술] 3. 코드이해하기 (0) | 2022.06.26 |